/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
#include <glib.h>
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <merc.h>
#include <tables.h>
#include <interp.h>
#include <fight.h>
/*
* Local functions.
*/
void crowd_brawl args( ( CHAR_DATA *ch ) );
bool check_dodge 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 ) );
void dam_message args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dam,
int dt ) );
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 ) );
void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
bool can_counter args( ( CHAR_DATA *ch) );
bool can_bypass args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
bool is_safe args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
int number_attacks args( ( CHAR_DATA *ch ) );
int dambonus args( ( CHAR_DATA *ch, CHAR_DATA *victim,
int dam, int stance) );
void update_damcap args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void show_fm args( ( CHAR_DATA *ch, char argument[MAX_STRING_LENGTH] ) );
void mob_forget args( ( CHAR_DATA *ch, MEM_DATA *memory ) );
bool check_safe_imm args( ( CHAR_DATA *ch ));
void wwf_wear args((CHAR_DATA *ch, OBJ_DATA *obj));
void retract_extra args((CHAR_DATA *ch));
void make_spirit args(( CHAR_DATA *ch));
GString *get_player_class_string args(( CHAR_DATA *ch ));
extern void calc_stat args((CHAR_DATA *ch, CHAR_DATA *victim));
extern bool check_artifact args(( CHAR_DATA *ch ));
void put_stance(CHAR_DATA *ch)
{
if (ch->stance[0] > 0)
return;
if (!IS_NPC(ch) && (IS_SET(ch->extra, EXTRA_STANCE)) )
{
switch (ch->stance[11])
{
case STANCE_VIPER: do_stance(ch,"viper"); break;
case STANCE_CRANE: do_stance(ch,"crane"); break;
case STANCE_CRAB: do_stance(ch,"crab"); break;
case STANCE_MONGOOSE: do_stance(ch,"mongoose"); break;
case STANCE_BULL: do_stance(ch,"bull"); break;
case STANCE_DRAGON: do_stance(ch,"dragon"); break;
case STANCE_MANTIS: do_stance(ch,"mantis"); break;
case STANCE_SWALLOW: do_stance(ch,"swallow"); break;
case STANCE_TIGER: do_stance(ch,"tiger"); break;
case STANCE_MONKEY: do_stance(ch,"monkey"); break;
default: do_stance(ch,"none"); break;
}
}
}
int pack_damroll_bonus(CHAR_DATA *ch)
{
CHAR_DATA *rch;
CHAR_DATA *rch_next;
/* First thing.. check the other members of the group */
for ( rch = ch->in_room->people; rch != NULL; rch = rch_next )
{
rch_next = rch->next_in_room;
if ( ch != rch && IS_CLASS(rch, CLASS_WEREWOLF) && is_same_group(ch, rch) )
return PACK_DAMBON;
}
return 0;
}
int pack_damcap_bonus(CHAR_DATA *ch)
{
CHAR_DATA *rch;
CHAR_DATA *rch_next;
/* First thing.. check the other members of the group */
for ( rch = ch->in_room->people; rch != NULL; rch = rch_next )
{
rch_next = rch->next_in_room;
if ( ch != rch && IS_CLASS(rch, CLASS_WEREWOLF) && is_same_group(ch, rch) )
return PACK_CAPBON;
}
return 0;
}
void show_brief(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *viewer;
for (viewer = ch->in_room->people; viewer != NULL; viewer = viewer->next_in_room)
{
if (!IS_NPC(viewer) && !IS_SET(viewer->act, PLR_BRIEF))
send_to_char(argument,viewer);
}
}
int soak_dam(CHAR_DATA *ch,CHAR_DATA *victim, int dam, int dt)
{
double tmp_dam;
int recover,start_dam,final_dam;
double accual_damage = 0;
char buf[MAX_STRING_LENGTH];
start_dam = dam;
tmp_dam = (double)dam;
if (victim == NULL || ch == NULL)
{
bug("Null victim or ch in Soak_dam",0);
return dam;
}
if ( !IS_NPC(victim) && IS_CLASS(victim, CLASS_WEREWOLF) && IS_SET(victim->special, SPC_WOLFMAN))
{
tmp_dam *= 0.6;
if (victim->pcdata->powers[WPOWER_BOAR] > 2 ) tmp_dam *= 0.7;
if (victim->pcdata->powers[WPOWER_BOAR] > 4 ) tmp_dam *= 0.7;
}
if ( !IS_NPC(victim) && IS_CLASS(victim,CLASS_SWWF))
{
/* carful on the soak here... the diffrent forms will give soak... close to vamp soak */
switch ( victim->pcdata->wwf_shape )
{
case SHAPE_HOMID:
break;
case SHAPE_GLABRO:
tmp_dam *= (0.9 - (victim->pcdata->rage_points/100)*0.1 / 3);
break;
case SHAPE_CRINOS:
tmp_dam *= (0.7 - (victim->pcdata->rage_points/100)*0.1 / 2);
break;
case SHAPE_HISPO:
tmp_dam *= (0.8 - (victim->pcdata->rage_points/100)*0.1 / 3);
break;
case SHAPE_LUPUS:
tmp_dam *= (0.9 - (victim->pcdata->rage_points/100)*0.1 / 3);
break;
}
}
/*Sanc Soak and Protect Soak, WAIT shouldn't this be in the soak proc?*/
if ( IS_AFFECTED(victim, AFF_SANCTUARY) && tmp_dam > 1 )
tmp_dam *= 0.5;
if ( IS_AFFECTED(victim, AFF_PROTECT) && IS_EVIL(ch) && tmp_dam > 1 )
tmp_dam -= tmp_dam * 0.25;
if (IS_ADDED(victim,ADDED_BRAGE) && victim->in_room->sector_type == SECT_FOREST)
tmp_dam *= .3;
if ( !IS_NPC(victim) && IS_CLASS(victim, CLASS_MAGE ))
{
if (has_sphere(victim,SPHERE_PRIME) >= 1) tmp_dam *= 0.9;
if (has_sphere(victim,SPHERE_SPIRIT) >= 2) tmp_dam *= 0.9;
if (has_sphere(victim,SPHERE_MIND) >= 3) tmp_dam *= 0.9;
if (has_sphere(victim,SPHERE_FORCES) >= 4) tmp_dam *= 0.9;
if (has_sphere(victim,SPHERE_LIFE) >= 5) tmp_dam *= 0.9;
if (has_sphere(victim,SPHERE_ENTROPY) >= 6) tmp_dam *= 0.9;
}
/* Check for weapon resistance - KaVir */
recover = 0;
if ( !IS_NPC(victim) && IS_IMMMERIT(victim, IMM_MERIT_SLASH) &&
(dt == TYPE_SLASH || dt == TYPE_SLICE) && tmp_dam > 0 )
recover = number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMMERIT(victim, IMM_MERIT_STAB) &&
(dt == TYPE_STAB || dt == TYPE_PIERCE) && tmp_dam > 0 )
recover = number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && get_disc(victim,DISC_VISCERATIKA) >= 6 &&
(dt == TYPE_STAB || dt == TYPE_PIERCE) && tmp_dam > 0 )
recover = number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMMERIT(victim, IMM_MERIT_SMASH) &&
(dt == TYPE_BLAST || dt == TYPE_POUND || dt == TYPE_CRUSH || dt == TYPE_HIT) && tmp_dam > 0 )
recover = number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMMERIT(victim, IMM_MERIT_ANIMAL) &&
(dt == TYPE_BITE || dt == TYPE_CLAW) && tmp_dam > 0 )
recover = number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMMERIT(victim, IMM_MERIT_MISC) &&
(dt == TYPE_GREP || dt == TYPE_SUCK || dt == TYPE_WHIP) && tmp_dam > 0 )
recover = number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMFLAW(victim, IMM_FLAW_SLASH) &&
(dt == TYPE_SLASH || dt == TYPE_SLICE) && tmp_dam > 0 )
recover -= number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMFLAW(victim, IMM_FLAW_STAB) &&
(dt == TYPE_STAB || dt == TYPE_PIERCE) && tmp_dam > 0 )
recover -= number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMFLAW(victim, IMM_FLAW_SMASH) &&
(dt == TYPE_BLAST || dt == TYPE_POUND || dt == TYPE_CRUSH || dt == TYPE_HIT) && tmp_dam > 0 )
recover -= number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMFLAW(victim, IMM_FLAW_ANIMAL) &&
(dt == TYPE_BITE || dt == TYPE_CLAW) && tmp_dam > 0 )
recover -= number_range(1,(int)tmp_dam);
if ( !IS_NPC(victim) && IS_IMMFLAW(victim, IMM_FLAW_MISC) &&
(dt == TYPE_GREP || dt == TYPE_SUCK || dt == TYPE_WHIP) && tmp_dam > 0 )
recover -= number_range(1,(int)tmp_dam);
/* Check for fortitude - KaVir */
if ( !IS_NPC(victim) && IS_CLASS(victim, CLASS_VAMPIRE)
&& get_disc(victim, DISC_FORTITUDE) > 0
&& victim->pcdata->condition[COND_THIRST] > 20
&& (dam-recover) > 0)
{
accual_damage = accual_damage+((dam-recover) * .005 *
number_range((5*(get_disc(victim, DISC_FORTITUDE) - 1)),
UMAX(100 - (5*(6 - get_disc(victim, DISC_FORTITUDE))),100)));
}
else if (IS_ITEMAFF(victim, ITEMA_RESISTANCE) && (dam-recover) > 0)
accual_damage = accual_damage+number_range(1,(dam-recover));
accual_damage = accual_damage+recover;
final_dam = (int)((double)start_dam - tmp_dam + accual_damage);
sprintf(buf,"@%s#%s^VICTSOAKAMOUNT/DAMAGE_TO_VICT: %d/%f",ch->name->str,victim->name->str,final_dam,tmp_dam);
show_fm(ch,buf);
tmp_dam -= accual_damage;
if (tmp_dam < 1)
tmp_dam = 0;
sprintf(buf,"@%s#%s^DAMAGEAFTERSOAK: %f",ch->name->str,victim->name->str,tmp_dam);
show_fm(ch,buf);
return (int)tmp_dam;
}
bool shape_crinos(CHAR_DATA *ch){
if (ch == NULL){
return FALSE;
}
if (IS_SWWF(ch) && ch->pcdata->wwf_shape == SHAPE_CRINOS){
return TRUE;
}
return FALSE;
}
/*
* Do one group of attacks.
*/
void multi_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
OBJ_DATA *wield;
OBJ_DATA *wield1;
OBJ_DATA *wield2;
int sn;
int level;
int chance;
int unarmed;
int wieldorig = 0;
int wieldtype = 0;
int maxcount;
int countup;
char buf[MSL],buf2[MSL];
switch(victim->plane){
case PLANE_ETHEREAL:
case PLANE_EARTH:
case PLANE_DEAD:
case PLANE_PUNISHMENT:
case PLANE_IMMORTAL:
case PLANE_SPIRIT:
send_to_char("You cannot damage anyone on this plane.\n\r",ch);
stop_fighting(ch,TRUE);
return;
}
if (!IS_NPC(ch)){
sprintf(buf,"@%s#%s^START OF ROUND",ch->name->str,victim->name->str);
show_fm(ch,buf);
sprintf(buf,"@%s#%s^HIT/DAM/HP/MANA/AC START: %d/%d/%d/%d/%d",ch->name->str,victim->name->str,ch->hitroll,ch->damroll,ch->hit,ch->mana,ch->armor);
show_fm(ch,buf);
sprintf(buf,"@%s#%s^CLASS: %d\n",ch->name->str,victim->name->str,ch->creature);
show_fm(ch,buf);
switch (ch->creature){
case CLASS_SWWF:
sprintf( buf, "@%s#%s^Breed %d %d %d",ch->name->str,victim->name->str,
ch->pcdata->breed[0],
ch->pcdata->breed[1],
ch->pcdata->breed[2]);
show_fm(ch,buf);
sprintf( buf, "@%s#%s^Auspice %d %d %d %d %d",ch->name->str,victim->name->str,
ch->pcdata->auspice[0], ch->pcdata->auspice[1],
ch->pcdata->auspice[2], ch->pcdata->auspice[3],
ch->pcdata->auspice[4]);
show_fm(ch,buf);
sprintf( buf, "@%s#%s^Tribes %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",ch->name->str,victim->name->str,
ch->pcdata->tribes[0], ch->pcdata->tribes[1], ch->pcdata->tribes[2],
ch->pcdata->tribes[3], ch->pcdata->tribes[4], ch->pcdata->tribes[5],
ch->pcdata->tribes[6], ch->pcdata->tribes[7], ch->pcdata->tribes[8],
ch->pcdata->tribes[9], ch->pcdata->tribes[10],ch->pcdata->tribes[11],
ch->pcdata->tribes[12],ch->pcdata->tribes[13],ch->pcdata->tribes[14],
ch->pcdata->tribes[15],ch->pcdata->tribes[16],ch->pcdata->tribes[17],
ch->pcdata->tribes[18],ch->pcdata->tribes[19]);
show_fm(ch,buf);
break;
case CLASS_VAMPIRE:
sprintf(buf,"@%s#%s^DISC: ",ch->name->str,victim->name->str);
for ( sn = 0 ; sn < MAX_DISC ; sn++ )
{
sprintf( buf2, " %d", ch->pcdata->disc[sn]);
strcat(buf,buf2);
}
show_fm(ch,buf);
break;
case CLASS_MAGE:
sprintf( buf, "@%s#%s^Sphere: ",ch->name->str,victim->name->str);
for (sn=0; sn < 20; sn++)
{
sprintf(buf2, " %d", ch->pcdata->powers[sn]);
strcat(buf,buf2);
}
show_fm(ch,buf);
break;
}
}
if ( ch->position < POS_SLEEPING ) return;
if ( dt == gsn_headbutt )
{
one_hit( ch, victim, dt, 1 );
return;
}
if ( ch == NULL || victim == NULL )
return;
if ( victim->name == NULL )
return;
if (!IS_NPC(ch) && IS_ITEMAFF(ch, ITEMA_PEACE))
{
send_to_char( "You are unable to attack them.\n\r", ch );
return;
}
//Rage them garou fast! WE WANT FRENZY!
if (!IS_NPC(ch) && IS_SWWF(ch) && ch->pcdata->rage_points < get_max_rage(ch) )
{
if (IS_ITEMAFF(ch, ITEMA_RAGER))
{
ch->pcdata->rage_points += number_range(25,100);
}
else
ch->pcdata->rage_points += number_range(5,25);
if (ch->pcdata->rage_points > get_max_rage(ch))
ch->pcdata->rage_points = get_max_rage(ch);
}
if (!IS_NPC(victim) && IS_ITEMAFF(victim, ITEMA_PEACE))
{
send_to_char( "You can't seem to attack them.\n\r", ch );
return;
}
wield1 = get_eq_char( ch, WEAR_WIELD );
wield2 = get_eq_char( ch, WEAR_HOLD );
if ( wield1 != NULL && wield1->item_type == ITEM_WEAPON ) wieldorig = 1;
if ( wield2 != NULL && wield2->item_type == ITEM_WEAPON ) wieldorig += 2;
wieldtype = wieldorig;
if ( wieldorig == 3 ) { if (number_range(1,2) == 2) wieldtype = 2; else wieldtype = 1;}
if ( wieldtype == 2 ) wield = wield2;
else wield = wield1;
if (!IS_NPC(ch) && ch->stance[0] > 0 && number_percent() == 1)
{
int stance = ch->stance[0];
if (ch->stance[stance] >= 200)
{
special_move(ch,victim);
sprintf(buf,"@%s#%s^END OF ROUND",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
}
//This is to set one out of 8 chances to do a special attack
unarmed = number_range(0,7);
/* the code below was altered by Spiral, I put one_hit
* back in the comments, due to we already track attacks
* later on in the code... why is this one here?
* -Spiral
*/
/* This one one_hit is needed to kick off the WHOLE fight
* pulse, heheh cute eh?, well don't take it out
* - Spiral
*/
if ( !IS_NPC(ch) && !shape_crinos(ch) && !IS_AFFECTED(ch, AFF_POLYMORPH) &&
ch->cmbt[unarmed] != 0 && wieldorig == 0 )
fightaction(ch,victim,ch->cmbt[unarmed], dt, wieldtype);
one_hit( ch, victim, dt, wieldtype );
if ( victim == NULL || victim->position != POS_FIGHTING )
return;
/* Only want one spell per round from spell weapons...otherwise it's
* too powerful, and would unbalance player killing (as this is a PK mud).
*/
/* this is base weapon spell code right here, kavir uses the
* number in Value[0] of a weapon with directly linked up to
* the skill_table number. (I have list skills to find this
* number, we all know how much it's a bitch to count those.
*/
if ( dt == TYPE_UNDEFINED )
{
dt = TYPE_HIT;
if ( wield != NULL && wield->item_type == ITEM_WEAPON )
{
dt += wield->value[3];
if (wield->value[0] >= 1)
{
/* Look, just don't ask... KaVir */
if (wield->value[0] >= 1000)
sn = wield->value[0] - ((wield->value[0] / 1000) * 1000);
else
sn = wield->value[0];
if (sn != 0 && victim->position == POS_FIGHTING && sn != 141)
(*skill_table[sn].spell_fun) (sn,wield->level,ch,victim);
}
}
}
if ( victim == NULL || victim->position != POS_FIGHTING )
return;
if ( ch->fighting != victim || dt == gsn_backstab || dt == gsn_headbutt )
return;
if ( !IS_NPC(victim) && !IS_SET(victim->special, SPC_WOLFMAN) &&
number_percent( ) <= victim->pcdata->learned[gsn_fastdraw] )
{
OBJ_DATA *obj;
int wpntype = 0;
int wpntype2 = 0;
if ((obj = get_eq_char(victim,WEAR_SCABBARD_R)) != NULL)
{
wpntype = obj->value[3];
if (wpntype < 0 || wpntype > 12) wpntype = 0;
if ((obj = get_eq_char(victim,WEAR_WIELD)) != NULL)
{
obj_from_char(obj);
obj_to_room(obj,victim->in_room);
act("You hurl $p aside.",victim,obj,NULL,TO_CHAR);
act("$n hurls $p aside.",victim,obj,NULL,TO_ROOM);
}
do_draw(victim,"right");
}
if ((obj = get_eq_char(victim,WEAR_SCABBARD_L)) != NULL)
{
wpntype2 = obj->value[3];
if (wpntype2 < 0 || wpntype2 > 12) wpntype2 = 0;
if ((obj = get_eq_char(victim,WEAR_HOLD)) != NULL)
{
obj_from_char(obj);
obj_to_room(obj,victim->in_room);
act("You hurl $p aside.",victim,obj,NULL,TO_CHAR);
act("$n hurls $p aside.",victim,obj,NULL,TO_ROOM);
}
do_draw(victim,"left");
}
if (wpntype > 0)
one_hit( victim, ch, TYPE_UNDEFINED, 1 );
if ( victim == NULL || victim->position != POS_FIGHTING )
return;
if (wpntype2 > 0)
one_hit( victim, ch, TYPE_UNDEFINED, 2 );
if ( victim == NULL || victim->position != POS_FIGHTING )
return;
}
// Count the number of attacks here and do them.
maxcount = number_attacks(ch);
if (!IS_NPC(ch))
{
chance = 0;
if (wield != NULL && wield->item_type == ITEM_WEAPON)
{
int tempnum = wield->value[3];
chance = (int)((double)ch->wpn[tempnum] * 0.5);
}
else chance = (int)((double)ch->wpn[0] * 0.5);
if (number_percent() <= chance) maxcount += 1;
}
if (wieldorig == 3)
maxcount += 1;
for (countup = 0; countup <= maxcount; countup++)
{
if (!IS_NPC(ch) && wieldorig == 0)
{
if (countup == 0) unarmed = number_range(0,3);
else if (countup == 1) unarmed = number_range(4,7);
else unarmed = number_range(0,7);
if ( !IS_NPC(ch) && !shape_crinos(ch) && !IS_AFFECTED(ch, AFF_POLYMORPH) &&
ch->cmbt[unarmed] != 0 && wieldorig == 0 )
{
fightaction(ch,victim,ch->cmbt[unarmed], dt, wieldtype);
continue;
}
}
wieldtype = wieldorig;
if ( wieldorig == 3 )
{
if (number_range(1,2) == 2) wieldtype = 2;
else wieldtype = 1;
}
one_hit( ch, victim, -1, wieldtype );
if ( victim == NULL || victim->position != POS_FIGHTING ){
sprintf(buf,"@%s#%s^END OF ROUND",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
if ( ch->fighting != victim ) {
sprintf(buf,"@%s#%s^END OF ROUND",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
}
if (!IS_NPC(ch) && !IS_FLAW(ch,FLAW_CLUMSY))
{
// Fangs get anorth try at battle GO FANGED ONES!
if (!IS_NPC(ch) && IS_VAMPAFF(ch,VAM_FANGS))
{
send_to_char("Your fangs inflict damage!\n\r",ch);
damage(ch,victim,30,TYPE_HIT);
}
if (!IS_NPC(ch) && IS_MOD(ch,MOD_TUSKS) && number_range(1,3) == 1)
{
send_to_char("Your tusks inflict damage!\n\r",ch);
damage(ch,victim,30,TYPE_HIT);
}
else if (!IS_NPC(ch) && IS_MOD(ch, MOD_HORNS) && number_range(1,5) == 1)
{
send_to_char("Your horns inflict damage!\n\r",ch);
damage(ch,victim,30,TYPE_HIT);
}
else if (!IS_NPC(ch) && IS_MERIT(ch,MERIT_AGILE) && number_range(1,5) == 1)
{
send_to_char("Your extra agility in combat inflicts damage!\n\r",ch);
damage(ch,victim,30,TYPE_HIT);
}
if (!IS_NPC(ch) && IS_ADDED(ch,ADDED_BRISTLES) && number_range(1,5) == 1)
{
send_to_char("One of your Bristles inflict damage!\n\r",ch);
damage(ch,victim,30,TYPE_HIT);
}
}
if ( victim == NULL || victim->position != POS_FIGHTING ){
sprintf(buf,"@%s#%s^END OF ROUND",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
//Do those nasty poison spits....
if (!IS_NPC(ch) && IS_CLASS(ch, CLASS_VAMPIRE) && get_disc(ch, DISC_SERPENTIS) > 0)
{
if ( (sn = skill_lookup( "poison" ) ) > 0)
(*skill_table[sn].spell_fun) (sn,ch->level*number_range(5,10),victim,ch);
}
if (!IS_NPC(ch) && IS_CLASS(ch, CLASS_WEREWOLF) && ch->pcdata->powers[WPOWER_SPIDER] > 0)
{
if ( (sn = skill_lookup( "poison" ) ) > 0)
(*skill_table[sn].spell_fun) (sn,ch->level*number_range(5,10) * ch->pcdata->powers[WPOWER_SPIDER],victim,ch);
}
if (IS_SET(ch->added, ADDED_HAND_FLAME) && number_percent() < 25)
{
if (IS_AFFECTED(victim,AFF_FLAMING) )
return;
SET_BIT(victim->affected_by, AFF_FLAMING);
act("You suddenly burst into flames!", victim, NULL, NULL, TO_CHAR);
act("$n suddenly bursts into flames!", victim, NULL, NULL, TO_ROOM);
}
// If your victim dont have a shield then why go further?
// - Spiral
if (victim->itemaffect < ITEMA_SHOCKSHIELD){
sprintf(buf,"@%s#%s^END OF ROUND",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
if (IS_NPC(victim) || victim->spl[1] < 4)
level = victim->level;
else
level = (int)((double)victim->spl[1] * 0.25);
if (IS_ITEMAFF(victim, ITEMA_SHOCKSHIELD) && ch->position == POS_FIGHTING)
if ( (sn = skill_lookup( "lightning bolt" ) ) > 0)
(*skill_table[sn].spell_fun) (sn,level,victim,ch);
if (IS_ITEMAFF(victim, ITEMA_FIRESHIELD) && ch->position == POS_FIGHTING)
if ( (sn = skill_lookup( "fireball" ) ) > 0)
(*skill_table[sn].spell_fun) (sn,level,victim,ch);
if (IS_ITEMAFF(victim, ITEMA_ICESHIELD) && ch->position == POS_FIGHTING)
if ( (sn = skill_lookup( "chill touch" ) ) > 0)
(*skill_table[sn].spell_fun) (sn,level,victim,ch);
if (IS_ITEMAFF(victim, ITEMA_ACIDSHIELD) && ch->position == POS_FIGHTING)
if ( (sn = skill_lookup( "acid blast" ) ) > 0)
(*skill_table[sn].spell_fun) (sn,level,victim,ch);
if (IS_ITEMAFF(victim, ITEMA_CHAOSSHIELD) && ch->position == POS_FIGHTING)
if ( (sn = skill_lookup( "chaos blast" ) ) > 0)
(*skill_table[sn].spell_fun) (sn,level,victim,ch);
//if ( victim == NULL || victim->position != POS_FIGHTING )
// return;
sprintf(buf,"@%s#%s^END OF ROUND",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
int number_attacks( CHAR_DATA *ch )
{
int count = 1;
char buf[MSL];
if ( IS_NPC(ch) )
{
if (ch->level >= 50) count += 1;
if (ch->level >= 100) count += 1;
if (ch->level >= 150) count += 3;
return count;
}
if ( IS_STANCE(ch, STANCE_VIPER) && number_percent() >
ch->stance[STANCE_VIPER] * 0.5) count += 1;
else if ( IS_STANCE(ch, STANCE_MANTIS) && number_percent() >
ch->stance[STANCE_MANTIS] * 0.5) count += 1;
else if ( IS_STANCE(ch, STANCE_TIGER) && number_percent() >
ch->stance[STANCE_TIGER] * 0.5) count += 1;
if (!IS_NPC(ch))
{
if ( IS_CLASS(ch, CLASS_VAMPIRE)
&& get_disc(ch, DISC_CELERITY) > 0
&& ch->pcdata->condition[COND_THIRST] > 20 )
{
count += get_disc(ch, DISC_CELERITY)/2;
if ( number_percent() < (get_disc(ch, DISC_CELERITY)%2 == 0 ? 33 : 66) )
count += 1;
}
if (IS_SWWF(ch))
count += get_max_rage(ch) / 150;
//Don't cross a Frenzyed garou...
if (IS_SWWF(ch) && IS_SET(ch->added, ADDED_FRENZY))
count += count;
if (IS_CLASS(ch, CLASS_WEREWOLF) && IS_SET(ch->special,SPC_WOLFMAN) )
{
if ( ch->pcdata->powers[WPOWER_LYNX] > 2 )
//count += 1;
count += number_range(0,2);
if ( ch->pcdata->powers[WPOWER_LYNX] > 4 )
//count += 1;
count += number_range(0,2);
if ( ch->pcdata->powers[WPOWER_SPHINX] > 1 )
//count += 1;
count += number_range(1,2);
if ( ch->pcdata->powers[WPOWER_RAT] > 2 )
//count += 1;
count += number_range(1,3);
//if ( ch->pcdata->powers[WPOWER_CHAMELEON] > 4 && number_range(1,30) == 17 )
if ( ch->pcdata->powers[WPOWER_CHAMELEON] > 4 && number_range(1,25) == 17 )
count *= 2;
}
if (IS_SET(ch->sphere_spaffect,AFSPHERE_SLOW_TIME) )
count -= number_range(1,3);
if (IS_SET(ch->sphere_spaffect,AFSPHERE_SPEED_TIME) )
count += number_range(1,3);
}
if ( IS_ITEMAFF(ch, ITEMA_SPEED) ) count += 1;
sprintf(buf,"@%s#%s^NUMBEROFATTACKS: %d",ch->name->str,ch->fighting->name->str,count);
show_fm(ch,buf);
return count;
}
void add_agony( CHAR_DATA *ch )
{
AFFECT_DATA paf;
if (!IS_NPC(ch) && ch->level > 2)
{
if (IS_AFFECTED(ch,AFF_AGGDAM))
return;
paf.type = MAX_SKILL + 1;
paf.modifier = 0;
paf.duration = -1;
paf.bitvector = AFF_AGGDAM;
paf.location = APPLY_NONE;
affect_to_char(ch,&paf);
}
}
/*
* Damage Mod Routine.. This function will add/subtract from inital damage and return
* final damage before soak. (Hope This will clear fight.c up a bit. - Spiral
*/
int damage_mod( CHAR_DATA *ch, CHAR_DATA *victim, int dt, int init_dam, OBJ_DATA *wield)
{
int stance;
OBJ_DATA *gloves;
double dam;
int form_bonus=0;
dam = init_dam;
/*
* Bonuses.
*/
/* Gift of Spragins :) */
if (IS_ADDED(ch,ADDED_ENLARGE))
dam += GS_DAMBON;
if (IS_ADDED(ch,ADDED_ENLARGE))
dam -= GS_DAMBON;
dam += char_damroll(ch);
/* Add PACK_DAMBON */
dam += pack_damroll_bonus(ch);
if ( !IS_AWAKE(victim) )
dam *= 2;
//need stance modifiers and imm's res's put in here too. -dc
/*
* Damage modifiers.
*/
if ( IS_AFFECTED(ch, AFF_HIDE) )
{
if (IS_CLASS(ch, CLASS_WEREWOLF) && IS_SET(ch->special,SPC_WOLFMAN) && ch->pcdata->powers[WPOWER_CHAMELEON] > 1 )
{
if (!can_see(victim,ch)) {dam *= 2.5;
send_to_char("You use your concealment to get a surprise attack!\n\r",ch);}
REMOVE_BIT( ch->affected_by, AFF_HIDE );
act( "$n leaps from $s concealment.", ch, NULL, NULL, TO_ROOM );
}
else
{
if (!can_see(victim,ch)) {dam *= 1.5;
send_to_char("You use your concealment to get a surprise attack!\n\r",ch);}
REMOVE_BIT( ch->affected_by, AFF_HIDE );
act( "$n leaps from $s concealment.", ch, NULL, NULL, TO_ROOM );
}
}
/* Bonus for Backstab */
if ( dt == gsn_backstab )
dam *= number_range(5,10);
if ( !IS_NPC(ch) && IS_VAMPAFF(ch,VAM_CLAWS) && get_auspice(ch, AUSPICE_AHROUN) > 0)
dam *= number_range( 2, 6);
/* Potence Bonus */
if ( !IS_NPC(ch) && IS_CLASS(ch, CLASS_VAMPIRE) &&
get_disc(ch, DISC_POTENCE) > 0 )
dam *= (.25 * get_disc(ch, DISC_POTENCE) + 1);
/* Bear 5 Bonus */
if ( !IS_NPC(ch) && IS_CLASS(ch, CLASS_WEREWOLF) && IS_SET(ch->special, SPC_WOLFMAN)
&& ch->pcdata->powers[WPOWER_BEAR] > 4)
dam *= ( number_range(5,16) / 4 );
/* Rat 2 Bonus */
if ( !IS_NPC(ch) && IS_CLASS(ch, CLASS_WEREWOLF) && IS_SET(ch->special, SPC_WOLFMAN)
&& ch->pcdata->powers[WPOWER_RAT] > 1)
dam *= 1.5;
/* Shark 2 Bonus */
if (!IS_NPC(ch) && ch->pcdata->powers[WPOWER_SHARK] >= 2 && dt == TYPE_BITE)
dam += dam * .1;
/* Shark 5 bonus */
if (!IS_NPC(ch) && ch->pcdata->powers[WPOWER_SHARK] >= 5 && dt == TYPE_BITE)
{
if (IS_CLASS(victim,CLASS_VAMPIRE))
{
victim->pcdata->condition[COND_THIRST] -= number_range(1,2);
}
if (IS_CLASS(victim,CLASS_WEREWOLF))
{
dam += dam * .2;
}
}
/* SpiralChild Bonus for shape */
if (!IS_NPC(ch) && IS_CLASS(ch,CLASS_SWWF))
{
switch ( ch->pcdata->wwf_shape )
{
case SHAPE_GLABRO:
form_bonus = (int)((double)((ch->pcdata->rage_points / 150) + 3) * .5);
break;
case SHAPE_CRINOS:
form_bonus = ch->pcdata->rage_points / 150 + 2;
break;
case SHAPE_HISPO:
form_bonus = (int)((double)((ch->pcdata->rage_points / 150) + 4) * .5);
break;
case SHAPE_LUPUS:
form_bonus = (int)((double)((ch->pcdata->rage_points / 150) + 3) * .5);
break;
}
dam *= ( .25 * (double)(form_bonus + 1) );
}
/* Garou Silver Bonus*/
if ( !IS_NPC(victim) && IS_SWWF(victim) )
{
if (wield != NULL && IS_SET(wield->spectype, SITEM_SILVER) && (get_auspice(victim,AUSPICE_RAGABASH) < 3))
{
if (number_range(1,100) < 10)
add_agony(victim);
dam *= 2;
}
else if ( ( gloves = get_eq_char( ch, WEAR_HANDS ) ) != NULL
&& IS_SET(gloves->spectype, SITEM_SILVER) && (get_auspice(victim,AUSPICE_RAGABASH) < 3))
{
if (number_range(1,100) < 10)
add_agony(victim);
dam *= 2;
}
}
/* Vampires should be tougher at night and weaker during the day. */
if ( !IS_NPC(ch) && IS_CLASS(ch, CLASS_VAMPIRE) )
{
switch (weather_info[ch->in_room->sector_type].sunlight)
{
case SUN_LIGHT:
if (IS_SET(ch->added,ADDED_NIGHTFALL))
dam *= 1.5;
else
dam /= 1.5;
case SUN_DARK:
dam *= 1.5;
default:
if (IS_SET(ch->added,ADDED_NIGHTFALL))
dam *= 1.5;
}
}
/* WTF is this? */
if ( !IS_NPC(ch) && dt >= TYPE_HIT)
dam = dam + (dam * ((ch->wpn[dt-1000]+1) / 100));
/* Bonus for Stances */
if ( !IS_NPC(ch) )
{
stance = ch->stance[0];
if ( IS_STANCE(ch, STANCE_NORMAL) ) dam *= 1.25;
else dam = dambonus(ch,victim,(int)dam,stance);
}
if ( dam <= 0 )
dam = 1;
return (int)dam;
}
bool check_hit(CHAR_DATA *ch, CHAR_DATA *victim, int dt, int level)
{
int thac0;
int thac0_00;
int thac0_32;
char buf[MAX_STRING_LENGTH]; //used for fight display - Spiral
int diceroll;
int victim_ac;
/*
* Calculate to-hit-armor-class-0 versus armor.
*/
if ( IS_NPC(ch) )
{
thac0_00 = 20;
thac0_32 = 0;
}
else
{
thac0_00 = SKILL_THAC0_00;
thac0_32 = SKILL_THAC0_32;
}
thac0 = interpolate( level, thac0_00, thac0_32 ) - char_hitroll(ch);
victim_ac = UMAX( -75, char_ac(victim) / 10 );
if ( !can_see( ch, victim ) )
victim_ac -= 4;
/* mod for shark */
if (!IS_NPC(ch) && ch->pcdata->powers[WPOWER_SHARK] >= 1 && dt == TYPE_BITE)
{
thac0 += (int)((double)thac0 * .2);
}
/*
* The moment of excitement!
*/
/* Not too sure of this while loop.. looks like shit to me.. but i'm not kavir... - Spiral */
while ( ( diceroll = number_bits( 5 ) ) >= 20 )
;
sprintf(buf,"@%s#%s^DICEROLL/Thac0 - Ac: %d/%d",ch->name->str,victim->name->str,diceroll,thac0 - victim_ac);
show_fm(ch, buf);
if (IS_NPC(ch) && IS_SET(ch->act,ACT_PLAYER_KILLER))
diceroll = 500;
if ( diceroll == 0
|| ( diceroll != 19 && diceroll < thac0 - victim_ac ) )
return FALSE;
else
return TRUE;
}
/*
* Hit one guy once.
*/
void one_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt, int handtype)
{
CHAR_DATA *org_victim = victim;
double dam;
int level;
OBJ_DATA *wield;
bool right_hand;
char buf[MAX_STRING_LENGTH]; //used for fight display - Spiral
/*
* Can't beat a dead char!
* Guard against weird room-leavings.
*/
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if (!IS_NPC(ch) && IS_ITEMAFF(ch, ITEMA_PEACE))
{
send_to_char( "You are unable to attack them.\n\r", ch );
return;
}
if (!IS_NPC(victim) && IS_ITEMAFF(victim, ITEMA_PEACE))
{
send_to_char( "You can't seem to attack them.\n\r", ch );
return;
}
sprintf(buf,"@%s#%s^START OF HIT",ch->name->str,victim->name->str);
show_fm(ch,buf);
/*
* Figure out the type of damage message.
*/
if (handtype == 2)
{
wield = get_eq_char( ch, WEAR_HOLD );
right_hand = FALSE;
}
else
{
wield = get_eq_char( ch, WEAR_WIELD );
right_hand = TRUE;
}
if (wield != NULL && IS_OBJ_STAT(wield,ITEM_FROZEN)){
send_to_char("The weapon you have wielded appears to be frozen in time.\n\r",ch);
stop_fighting(ch,TRUE);
return;
}
if ( dt == TYPE_UNDEFINED )
{
dt = TYPE_HIT;
if ( wield != NULL && wield->item_type == ITEM_WEAPON )
dt += wield->value[3];
}
if (ch->wpn[dt-1000] > 5)
level = (ch->wpn[dt-1000] / 5);
else
level = 1;
if (level > 40)
level = 40;
if(!check_hit(ch,victim,dt,level))
{
/* Miss. */
damage( ch, victim, 0, dt );
if (!is_safe(ch,victim))
{
improve_wpn(ch,dt,right_hand);
improve_stance(ch);
}
sprintf(buf,"@%s#%s^END OF HIT",ch->name->str,victim->name->str);
show_fm(ch,buf);
tail_chain( );
return;
}
/*
* Hit.
* Calc damage.
*/
if ( IS_NPC(ch) )
{
dam = number_range( ch->level / 2, ch->level * 3 / 2 );
if ( wield != NULL )
dam += dam * 0.5;
}
else
{
if ( IS_VAMPAFF(ch,VAM_CLAWS) && wield == NULL)
{
dam = number_range( 10, 20 );
dt = TYPE_CLAW;
}
else if ( wield != NULL && wield->item_type == ITEM_WEAPON )
dam = number_range( wield->value[1], wield->value[2] );
else
dam = number_range( 1, 4 );
}
sprintf(buf,"@%s#%s^STANCE THIS HIT: %f",ch->name->str,victim->name->str,dam);
show_fm(ch,buf);
sprintf(buf,"@%s#%s^DAMAGEBEFOREMOD: %f",ch->name->str,victim->name->str,dam);
show_fm(ch,buf);
//Modifiy damage from inital
dam = damage_mod(ch,victim,dt,(int)dam,wield);
sprintf(buf,"@%s#%s^DAMAGEAFTERMOD: %f",ch->name->str,victim->name->str,dam);
show_fm(ch,buf);
/* Add check for agony bit here.. */
if ( wield !=NULL && wield->value[0] == 141 )
add_agony(victim);
/* Confuse will make the attacker the victim for a round */
if (IS_SET(ch->added,ADDED_CONFUSE))
{
org_victim = victim;
victim = ch;
}
sprintf(buf,"@%s#%s^DAMAGE BEFORE DAMAGE CALL: %f",ch->name->str,victim->name->str,dam);
show_fm(ch,buf);
damage( ch, victim, (int)dam, dt );
if (!is_safe(ch,victim))
{
improve_wpn(ch,dt,right_hand);
improve_stance(ch);
}
if (ch == victim && !IS_ADDED(ch,ADDED_CONFUSE))
{
stop_fighting(ch,TRUE);
}
if (IS_SET(ch->added,ADDED_CONFUSE))
{
REMOVE_BIT(ch->added,ADDED_CONFUSE);
victim = org_victim;
}
sprintf(buf,"@%s#%s^END OF HIT",ch->name->str,victim->name->str);
show_fm(ch,buf);
tail_chain( );
return;
}
bool can_counter( CHAR_DATA *ch)
{
if (!IS_NPC(ch) && IS_STANCE(ch, STANCE_MONKEY)) return TRUE;
return FALSE;
}
bool can_bypass( CHAR_DATA *ch, CHAR_DATA *victim )
{
if (IS_NPC(ch) || IS_NPC(victim)) return FALSE;
else if (IS_STANCE(ch, STANCE_VIPER)) return TRUE;
else if (IS_STANCE(ch, STANCE_MANTIS)) return TRUE;
else if (IS_STANCE(ch, STANCE_TIGER)) return TRUE;
return FALSE;
}
void update_damcap( CHAR_DATA *ch, CHAR_DATA *victim )
{
int max_dam = 1000;
int lurf_dam = 4; // damage modifier for Lurf - Dominion
int npc_mod = 20;
if (!IS_NPC(ch))
{
if (IS_CLASS(ch, CLASS_VAMPIRE))
{
if (ch->pcdata->stats[UNI_GEN] <= 3) max_dam = 1500 * lurf_dam;
else if (ch->pcdata->stats[UNI_GEN] <= 4) max_dam = 1400 * lurf_dam;
else if (ch->pcdata->stats[UNI_GEN] <= 5) max_dam = 1300 * lurf_dam;
else max_dam = 1200 * lurf_dam;
max_dam += (ch->pcdata->stats[UNI_RAGE] * 10);
if (get_disc(ch, DISC_POTENCE) > 0) max_dam += 150 *
get_disc(ch, DISC_POTENCE) * lurf_dam;
if (ch->pcdata->rank == AGE_METHUSELAH) max_dam += 500 * lurf_dam;
else if (ch->pcdata->rank == AGE_ELDER) max_dam += 300 * lurf_dam;
else if (ch->pcdata->rank == AGE_ANCILLA) max_dam += 200 * lurf_dam;
}
else if (IS_SET(ch->special, SPC_WOLFMAN))
{
max_dam = 2000 * lurf_dam;
max_dam += pack_damcap_bonus(ch);
max_dam += (ch->pcdata->stats[UNI_RAGE] * 10); /* rage * 10 */
max_dam += (((get_age(ch) - 17) * 2 ) * 2); /* hours * 2 */
if (ch->pcdata->powers[WPOWER_BEAR] > 4) max_dam += 250 * lurf_dam;
if (ch->pcdata->powers[WPOWER_RAT] > 2) max_dam += 250 * lurf_dam;
}
else if (IS_SWWF(ch))
{
max_dam = 2000 * lurf_dam;
max_dam += pack_damcap_bonus(ch);
max_dam += (ch->pcdata->rage_points * 10); /* rage * 10 */
max_dam += (((get_age(ch) - 17) * 2 ) * 2); /* hours * 2 */
switch ( ch->pcdata->wwf_shape )
{
case SHAPE_GLABRO:
max_dam += 250 * lurf_dam;
break;
case SHAPE_CRINOS:
max_dam += 350 * lurf_dam;
break;
case SHAPE_HISPO:
max_dam += 300 * lurf_dam;
break;
case SHAPE_LUPUS:
max_dam += 200 * lurf_dam;
break;
}
}
else if (IS_CLASS(ch, CLASS_MAGE))
{
max_dam += ((((get_age(ch) - 17) * 2 ) * lurf_dam * 2));
if (has_sphere(ch,SPHERE_FORCES) > 3) max_dam += 100 *
has_sphere(ch,SPHERE_FORCES) * lurf_dam;
}
if (IS_ITEMAFF(ch, ITEMA_ARTIFACT)) max_dam += 500 * lurf_dam;
if (IS_ITEMAFF(victim, ITEMA_ARTIFACT)) max_dam -= 500 * lurf_dam;
if (IS_NPC(victim) || victim->stance[0] != STANCE_MONKEY)
{
if (ch->stance[0] == STANCE_BULL) max_dam += 200 * lurf_dam;
else if (ch->stance[0] == STANCE_DRAGON) max_dam += 250 * lurf_dam;
else if (ch->stance[0] == STANCE_TIGER) max_dam += 200 * lurf_dam;
}
}
else max_dam += (ch->level * npc_mod * lurf_dam);
if (!IS_NPC(victim))
{
int silver_tol = (int)((double)victim->pcdata->powers[WPOWER_SILVER] * 2.5);
if (IS_CLASS(victim, CLASS_WEREWOLF) &&
IS_ITEMAFF(ch, ITEMA_RIGHT_SILVER))
max_dam += (250 - silver_tol);
if (IS_CLASS(victim, CLASS_WEREWOLF) &&
IS_ITEMAFF(ch, ITEMA_LEFT_SILVER))
max_dam += (250 - silver_tol);
if (IS_NPC(ch) || ch->stance[0] != STANCE_MONKEY)
{
if (victim->stance[0] == STANCE_CRAB) max_dam -= 250 * lurf_dam;
else if (victim->stance[0] == STANCE_DRAGON) max_dam -= 250 * lurf_dam;
else if (victim->stance[0] == STANCE_SWALLOW) max_dam -= 250 * lurf_dam;
}
}
if (max_dam < 1000 * lurf_dam) max_dam = 1000 * lurf_dam;
/* fair beating your self! */
ch->damcap[DAM_CAP] = max_dam;
ch->damcap[DAM_CHANGE] = 0;
return;
}
/*
* Inflict damage from a hit.
*/
void damage( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt )
{
int max_dam = ch->damcap[DAM_CAP];
char buf[MAX_STRING_LENGTH]; //To show fight varibles in action - Spiral
sprintf(buf,"@%s#%s^START_DAMAGE",ch->name->str,victim->name->str);
show_fm(ch,buf);
if ( victim->position == POS_DEAD )
return;
if (check_safe_imm(ch))
return;
if (HAS_DELAY(victim) || HAS_DELAY(ch))
return;
switch(victim->plane){
case PLANE_ETHEREAL:
case PLANE_EARTH:
case PLANE_DEAD:
case PLANE_PUNISHMENT:
case PLANE_IMMORTAL:
case PLANE_SPIRIT:
return;
}
/*
* Stop up any residual loopholes. -- NOT RIGHT
* Damcap can update during a fight... - Spiral
*/
sprintf(buf,"@%s#%s^DAMCAPBEFORE: %d",ch->name->str,victim->name->str,ch->damcap[DAM_CAP]);
show_fm(ch,buf);
update_damcap(ch,victim);
sprintf(buf,"@%s#%s^DAMCAPAFTER: %d",ch->name->str,victim->name->str,ch->damcap[DAM_CAP]);
show_fm(ch,buf);
if ( ch == victim )
max_dam = 1000;
if ( dam > max_dam ) dam = max_dam;
/*
* Certain attacks are forbidden.
* Most other attacks are returned.
*/
if ( is_safe( ch, victim ) )
{
send_to_char("Not in a safe area.\n\r",ch);
return;
}
check_killer( ch, victim );
if (check_pk_range(victim,ch)){
victim->last_attacked = ch;
set_attack_flag(ch,victim);
}
if ( victim->position > POS_STUNNED && ch != victim && ch->in_room == victim->in_room )
{
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 );
}
victim->position = POS_FIGHTING;
}
if ( victim->position > POS_STUNNED && ch != victim && ch->in_room == victim->in_room)
{
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;
}
}
/*
* More charm stuff.
*/
if ( victim->master == ch )
stop_follower( victim );
if ( dam < 0 )
dam = 0;
/*
* Check for disarm, trip, parry, and dodge.
*/
if ( dt >= TYPE_HIT && ch != victim )
{
if ( IS_NPC(ch) && number_percent( ) < ch->level * 0.5 )
disarm( ch, victim );
if ( IS_NPC(ch) && number_percent( ) < ch->level * 0.5 )
trip( ch, victim );
if ( check_parry( ch, victim, dt ) ){
sprintf(buf,"@%s#%s^PARRYED1",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
if ( !IS_NPC(victim) && IS_STANCE(victim, STANCE_CRANE) &&
victim->stance[STANCE_CRANE] > 100 && !can_counter(ch)
&& !can_bypass(ch,victim) && check_parry( ch, victim, dt )){
sprintf(buf,"@%s#%s^PARRYED2",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
else if ( !IS_NPC(victim) && IS_STANCE(victim, STANCE_MANTIS) &&
victim->stance[STANCE_MANTIS] > 100 && !can_counter(ch)
&& !can_bypass(ch,victim) && check_parry( ch, victim, dt )){
sprintf(buf,"@%s#%s^PARRYED3",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
if ( check_dodge( ch, victim, dt ) ){
sprintf(buf,"@%s#%s^DODGED",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
if ( !IS_NPC(victim) && IS_STANCE(victim, STANCE_MONGOOSE) &&
victim->stance[STANCE_MONGOOSE] > 100 && !can_counter(ch)
&& !can_bypass(ch,victim) && check_dodge( ch, victim, dt )){
sprintf(buf,"@%s#%s^DAMAGE_AVOIDED1",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
else if ( !IS_NPC(victim) && IS_STANCE(victim, STANCE_SWALLOW) &&
victim->stance[STANCE_SWALLOW] > 100 && !can_counter(ch)
&& !can_bypass(ch,victim) && check_dodge( ch, victim, dt )){
sprintf(buf,"@%s#%s^DAMAGE_AVOIDED2",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
}
/* Call to soak proc - Spiral */
sprintf(buf,"@%s#%s^DAMAGE BEFORE SOAK: %d",ch->name->str,victim->name->str,dam);
show_fm(ch,buf);
dam = soak_dam(ch,victim, dam,dt);
/* this is the only dam mod after damcap for Player killers */
if (IS_NPC(ch) && IS_SET(ch->act,ACT_PLAYER_KILLER))
{
sprintf(buf,"@%s#%s^PLAYER_KILLER_BITSET",ch->name->str,victim->name->str);
show_fm(ch,buf);
dam = dam * ch->level;
if ( dam > max_dam ) dam = max_dam;
}
dam_message( ch, victim, dam, dt );
sprintf(buf,"@%s#%s^DAMAGE_TO_VICT/HP_BEFORE: %d/%d",ch->name->str,victim->name->str,dam,victim->hit);
show_fm(ch,buf);
hurt_person(ch,victim,dam);
/*
* Check for aggrivated damage if the garou have luna's avenger..
*/
if (IS_SET(ch->added, ADDED_LUNAAVENGER) && IS_CLASS(victim,CLASS_SWWF) && dt == TYPE_CLAW){
add_agony(victim);
act("Your silver claws causes aggrivated damage to $N!",ch,NULL,victim,TO_CHAR);
act("$n's silver claws causes aggrivated damage to you!",ch,NULL,victim,TO_VICT);
act("$n's silver claws causes aggrivated damage to $N!",ch,NULL,victim,TO_NOTVICT);
}
sprintf(buf,"@%s#%s^VICT_HITPOINTS: %d",ch->name->str,victim->name->str,victim->hit);
show_fm(ch,buf);
sprintf(buf,"@%s#%s^END_DAMAGE",ch->name->str,victim->name->str);
show_fm(ch,buf);
return;
}
/*
** adv_damage
*
* FILENAME: C:\lurfcode\fight.c
*
* PARAMETERS:
*
* DESCRIPTION: Is this function even used?
*
* RETURNS:
*
*/
void adv_damage( CHAR_DATA *ch, CHAR_DATA *victim, int dam )
{
if ( victim->position == POS_DEAD )
return;
if ( dam > 1000 ) dam = 1000;
if ( victim != ch )
{
if ( is_safe( ch, victim ) )
return;
check_killer( ch, victim );
if ( victim->position > POS_STUNNED )
{
if ( victim->fighting == NULL )
set_fighting( victim, ch );
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;
}
}
if ( victim->master == ch )
stop_follower( victim );
if ( IS_AFFECTED(victim, AFF_SANCTUARY) && dam > 1 )
dam /= 2;
if ( IS_AFFECTED(victim, AFF_PROTECT) && IS_EVIL(ch) && dam > 1 )
dam -= dam / 4;
if ( dam < 0 )
dam = 0;
}
return;
}
void hurt_person( CHAR_DATA *ch, CHAR_DATA *victim, int dam )
{
SPHERE_DATA *paf;
OBJ_DATA *to_obj;
/* bool is_npc = FALSE; Taken this out -- Spiral*/
char buf[MAX_STRING_LENGTH];
int spirit_percent = 0; /*!< The percent value to compare to create a spirit */
/*
* Hurt the victim.
* Inform the victim of his new state.
*/
if (IS_SET(victim->sphere_spaffect, AFSPHERE_MANA_SHIELD))
{
if ( victim->hit <= 5000 || dam > victim->hit )
{
if ( victim->mana >= 200 )
victim->mana -= dam;
else
{
paf = find_spaffect(victim,AFSPHERE_MANA_SHIELD);
sphere_remove(victim,paf);
victim->hit -= dam;
}
}
else
victim->hit -= dam;
}
else
victim->hit -= dam;
/* Start doing reverse damage here....*/
if (IS_SWWF(victim) && get_tribe(victim, TRIBE_GET_OF_FENRIS) >= 1 && ch != victim)
{
send_to_char("Your venom blood starts to spill.\n\r",ch);
damage(victim,ch,number_range(1,100) * get_tribe(ch,TRIBE_GET_OF_FENRIS),TYPE_POISON);
}
if ( !IS_NPC(victim)
&& victim->level >= LEVEL_IMMORTAL
&& victim->hit < 1 )
victim->hit = 1;
update_pos( victim );
switch( victim->position )
{
case POS_MORTAL:
if (IS_SET(victim->act, PLR_WIZINVIS))
{
REMOVE_BIT(victim->act, PLR_WIZINVIS);
act("$N reappears.",NULL,NULL,victim,TO_ROOM);
send_to_char("You become unvanished.\n\r",victim);
}
act( "$n is mortally wounded, and spraying blood everywhere.",
victim, NULL, NULL, TO_ROOM );
send_to_char(
"You are mortally wounded, and spraying blood everywhere.\n\r",
victim );
if (IS_SWWF(victim))
shape_shift(victim, SHAPE_HOMID);
break;
case POS_INCAP:
act( "$n is incapacitated, and bleeding badly.",
victim, NULL, NULL, TO_ROOM );
send_to_char(
"You are incapacitated, and bleeding badly.\n\r",
victim );
if (IS_SWWF(victim))
shape_shift(victim, SHAPE_HOMID);
break;
case POS_STUNNED:
act( "$n is stunned, but will soon recover.",
victim, NULL, NULL, TO_ROOM );
send_to_char("You are stunned, but will soon recover.\n\r",
victim );
break;
case POS_DEAD:
if (IS_SET(victim->affected_by,AFF_GHOST)){
victim->plane = PLANE_SPIRIT;
shift_obj_plane(ch);
act("$N fades back in to the spirit world.",ch,NULL,victim,TO_CHAR);
act("$n has been sent back in to the spirit world.",victim,NULL,NULL,TO_ROOM);
stop_fighting(ch,TRUE);
break;
}
/* Send MSP String if triggered */
if ( IS_SET(ch->deaf, CHANNEL_MSP ))
{
int midnum;
midnum = number_range( 0, MAX_WAV_SCREAM );
/*play Manson only one song for now.. */
sprintf(buf,"\n\r!!SOUND(%s T=sound L=1 V=100 U=http://%s%s )\n\r",msp_scream_table[midnum].msp_string, msp_scream_table[midnum].msp_server, msp_scream_table[midnum].msp_dirinfo);
send_to_char(buf,ch);
if ( IS_SET(victim->deaf, CHANNEL_MSP ))
send_to_char(buf,victim);
}
act( "$n is DEAD!!", victim, 0, 0, TO_ROOM );
act( "$n is DEAD!!", victim, 0, 0, TO_CHAR );
send_to_char( "{RYou have been KILLED!!{x\n\r\n\r", victim );
playwave_toch(victim,9);
break;
default:
if ( dam > victim->max_hit / 4 )
send_to_char( "{RThat really did HURT!{x\n\r", victim );
if ( victim->hit < victim->max_hit / 4 && dam > 0 )
{
if (!IS_NPC(victim) && IS_CLASS(victim, CLASS_VAMPIRE)
&& number_percent() < victim->beast)
vamp_rage(victim);
else
send_to_char( "{RYou sure are {rBLEEDING!{x\n\r", victim );
}
break;
}
/*
* Sleep spells and extremely wounded folks.
*/
if ( !IS_AWAKE(victim) )
stop_fighting( victim, FALSE );
/*
* Payoff for killing things.
*/
if ( victim->position == POS_DEAD )
{
MEM_DATA *remember;
group_gain( ch, victim );
if ( !IS_NPC(victim) )
{
sprintf( log_buf, "%s killed by %s at %d",
victim->name->str,
(IS_NPC(ch) ? ch->short_descr->str : ch->name->str),
victim->in_room->vnum );
log_string2( log_buf );
logchan(log_buf, NULL, NULL,WIZ_DEATHS,0, LEVEL_IMMORTAL);
/*
* Dying penalty:
* 1/2 your current exp.
*/
if ( victim->exp > 0 )
victim->exp = victim->exp / 2;
}
if (IS_NPC(victim) && !IS_NPC(ch))
{
/* add in gore! */
if ((IS_SET(victim->act,ACT_HUMAN)) && ch->blood_count > 1 )
{
ch->blood_count++;
send_to_char("{RYou become covered in blood and gore.{x\n\r",ch);
}
ch->mkill += 1;
if (ch->level == 1 && ch->mkill > 14)
{
ch->level = 2;
do_save(ch,"");
}
}
if ( (remember = get_mem_data(ch, victim)) != NULL)
{
if ( IS_SET(remember->reaction, MEM_AFRAID) || IS_SET(remember->reaction, MEM_HOSTILE))
mob_forget(ch,remember);
}
if (!IS_NPC(victim) && IS_NPC(ch))
{
victim->mdeath = victim->mdeath + 1;
}
/*
* 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 ( HAS_PROG(ch->in_room, TRIG_DEATH) )
rprog_percent_trigger(ch->in_room, ch, NULL, NULL, TRIG_DEATH);
for ( to_obj = ch->in_room->contents; to_obj; to_obj = to_obj->next_content )
{
if ( HAS_PROG(to_obj->pIndexData, TRIG_DEATH) )
oprog_percent_trigger(to_obj, ch, NULL, NULL, TRIG_DEATH);
}
/*
* This is a real random chance that when a mobile dies
* a Restless Spirit is Born to deal with.
* Make it resemble the old mob and at least 1/10 it's stats
* NO strength
*/
spirit_percent = number_percent();
if ( !IS_NPC(ch) && IS_NPC(victim)
&& 1 < spirit_percent
&& number_range(1,100) == spirit_percent
&& victim->pIndexData->vnum != MOB_VNUM_RESTLESS_SPIRIT)
make_spirit(victim);
victim->killed_by = ch;
raw_kill( victim );
if ( IS_SET(ch->act, PLR_AUTOLOOT) )
do_get( ch, "all corpse" );
//else
// do_look( ch, "in corpse" );
if ( !IS_NPC(ch) && IS_NPC(victim) )
{
if ( IS_SET(ch->act, PLR_AUTOSAC) )
do_sacrifice( ch, "corpse" );
}
return;
}
if ( victim == ch )
return;
/*
* Take care of link dead people.
*/
if ( !IS_NPC(victim) && victim->desc == NULL )
{
if ( number_range( 0, victim->wait ) == 0 )
{
do_flee( victim, "" );
/* do_recall( victim, "" ); */
return;
}
}
/*
* Wimp out?
*/
if ( IS_NPC(victim) && dam > 0 )
{
if ( ( IS_SET(victim->act, ACT_WIMPY) && number_bits( 1 ) == 0
&& victim->hit < victim->max_hit / 2 )
|| ( 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 == 0 )
do_flee( victim, "" );
else if (IS_AFFECTED(victim, AFF_FEAR))
do_flee(victim,"");
tail_chain( );
return;
}
/*
* Check for parry.
*/
bool check_parry( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
OBJ_DATA *obj = NULL;
int chance = 0;
bool claws = FALSE;
char buf[MSL];
if ( !IS_AWAKE(victim) )
return FALSE;
if (IS_SWWF(victim) && IS_VAMPAFF(victim, VAM_CLAWS))
{
claws = TRUE;
}
else if ( IS_CLASS(victim, CLASS_WEREWOLF) &&
victim->pcdata->powers[WPOWER_BEAR] > 2 &&
IS_VAMPAFF(victim, VAM_CLAWS) &&
get_eq_char(victim, WEAR_WIELD) == NULL &&
get_eq_char(victim, WEAR_HOLD) == NULL)
{
claws = TRUE;
}
else
{
if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL
|| obj->item_type != ITEM_WEAPON )
{
if ( ( obj = get_eq_char( victim, WEAR_HOLD ) ) == NULL
|| obj->item_type != ITEM_WEAPON ) return FALSE;
}
}
if (dt < 1000 || dt > 1012)
return FALSE;
if (!IS_NPC(ch))
chance -= (int)((double)ch->wpn[dt-1000] * 0.1);
else
chance -= (int)((double)ch->level * 0.2);
if (!IS_NPC(victim))
chance += (int)((double)victim->wpn[dt-1000] * 0.5);
else
chance += victim->level;
if (!IS_NPC(victim) && IS_STANCE(victim, STANCE_CRANE) &&
victim->stance[STANCE_CRANE] > 0 && !can_counter(ch) &&
!can_bypass(ch,victim))
chance += (int)((double)victim->stance[STANCE_CRANE] * 0.25);
else if (!IS_NPC(victim) && IS_STANCE(victim, STANCE_MANTIS) &&
victim->stance[STANCE_MANTIS] > 0 && !can_counter(ch) &&
!can_bypass(ch,victim))
chance += (int)((double)victim->stance[STANCE_MANTIS] * 0.25);
chance -= (int)((double)char_hitroll(ch) * 0.1);
if (claws)
{
if ( victim->pcdata->powers[WPOWER_LYNX] > 3 )
chance += (int)((double)char_hitroll(victim) * 0.1);
else
chance += (int)((double)char_hitroll(victim) * 0.075);
}
else
chance += (int)((double)char_hitroll(victim) * 0.1);
if (!IS_NPC(ch))
{
if (get_disc(ch, DISC_CELERITY) > 0 &&
IS_CLASS(ch, CLASS_VAMPIRE))
{
chance -= 20;
chance -= get_disc(ch, DISC_CELERITY) * 2;
}
if (IS_CLASS(ch, CLASS_WEREWOLF) &&
ch->pcdata->powers[WPOWER_MANTIS] < 5 )
chance -= (ch->pcdata->powers[WPOWER_MANTIS] * 5);
}
if (!IS_NPC(victim) && IS_SWWF(victim))
{
switch ( victim->pcdata->wwf_shape )
{
case SHAPE_GLABRO:
chance += number_range(5,15);
break;
case SHAPE_CRINOS:
chance += number_range(15,25);
break;
case SHAPE_HISPO:
chance += number_range(10,20);
break;
case SHAPE_LUPUS:
chance += number_range(5,15);
break;
}
}
if (!IS_NPC(victim))
{
if (get_disc(victim, DISC_CELERITY) > 0 &&
IS_CLASS(victim, CLASS_VAMPIRE))
{
chance += 20;
chance += get_disc(victim, DISC_CELERITY) * 2;
}
}
if (!IS_NPC(ch) && get_disc(ch, DISC_CELERITY) > 0 &&
IS_CLASS(ch, CLASS_VAMPIRE))
{ // 8,5,2
if (ch->pcdata->rank == AGE_METHUSELAH) chance -= 5;
else if (ch->pcdata->rank == AGE_ELDER) chance -= 3;
else if (ch->pcdata->rank == AGE_ANCILLA) chance -= 1;
}
if (!IS_NPC(victim) && get_disc(victim, DISC_CELERITY) > 0 &&
IS_CLASS(victim, CLASS_VAMPIRE))
{
if (victim->pcdata->rank == AGE_METHUSELAH) chance += 5;
else if (victim->pcdata->rank == AGE_ELDER) chance += 3;
else if (victim->pcdata->rank == AGE_ANCILLA) chance += 1;
}
if (chance > 75) chance = 75;
else if (chance < 25) chance = 25;
sprintf(buf,"@%s#%s^PARRYCHANCE: %d",ch->name->str,victim->name->str,chance);
show_fm(ch,buf);
if ( number_percent( ) < 100 && number_percent( ) >= chance )
return FALSE;
if (claws)
{
if (IS_NPC(victim) || !IS_SET(victim->act, PLR_BRIEF))
act( "You parry $n's blow with your claws.", ch, NULL, victim, TO_VICT );
if (IS_NPC(ch) || !IS_SET(ch->act, PLR_BRIEF))
act( "$N parries your blow with $S claws.", ch, NULL, victim, TO_CHAR );
act( "$N parries $n's blow with $S claws.", ch, NULL, victim, TO_NOTVICTBR );
return TRUE;
}
if (!IS_NPC(victim) && obj != NULL && obj->item_type == ITEM_WEAPON &&
obj->value[3] >= 0 && obj->value[3] <= 12)
{
if (IS_NPC(victim) || !IS_SET(victim->act, PLR_BRIEF))
act( "You parry $n's blow with $p.", ch, obj, victim, TO_VICT );
if (IS_NPC(ch) || !IS_SET(ch->act, PLR_BRIEF))
act( "$N parries your blow with $p.", ch, obj, victim, TO_CHAR );
act( "$N parries $n's blow with $p.", ch, obj, victim, TO_NOTVICTBR );
return TRUE;
}
if (IS_NPC(victim) || !IS_SET(victim->act, PLR_BRIEF))
act( "You parry $n's attack.", ch, NULL, victim, TO_VICT );
if (IS_NPC(ch) || !IS_SET(ch->act, PLR_BRIEF))
act( "$N parries your attack.", ch, NULL, victim, TO_CHAR );
act( "$N parries $n's attack.", ch, NULL, victim, TO_NOTVICTBR );
return TRUE;
}
/*
* Check for dodge.
*/
bool check_dodge( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
char buf[MAX_STRING_LENGTH];
int chance = 0;
int roll_a,roll_b;
if ( !IS_AWAKE(victim) )
return FALSE;
if (!IS_NPC(ch)) chance -= (int)((double)ch->wpn[dt-1000] * 0.1);
else chance -= (int)((double)ch->level * 0.2);
if (!IS_NPC(victim)) chance += (int)((double)victim->wpn[0] * 0.5);
else chance += victim->level;
if (!IS_NPC(victim) && IS_STANCE(victim, STANCE_MONGOOSE) &&
victim->stance[STANCE_MONGOOSE] > 0 && !can_counter(ch) &&
!can_bypass(ch,victim))
(chance += (int)((double)victim->stance[STANCE_MONGOOSE] * 0.25));
if (!IS_NPC(victim) && IS_STANCE(victim, STANCE_SWALLOW) &&
victim->stance[STANCE_SWALLOW] > 0 && !can_counter(ch) &&
!can_bypass(ch,victim))
(chance += (int)((double)victim->stance[STANCE_SWALLOW] * 0.25));
if (!IS_NPC(ch))
{
if (get_disc(ch, DISC_CELERITY) > 0 &&
IS_CLASS(ch, CLASS_VAMPIRE))
{
chance -= 20;
chance -= get_disc(ch, DISC_CELERITY) * 2;
}
else if (IS_CLASS(ch, CLASS_WEREWOLF) &&
ch->pcdata->powers[WPOWER_MANTIS] < 5 )
chance -= (ch->pcdata->powers[WPOWER_MANTIS] * 10);
}
if (!IS_NPC(victim))
{
if (get_disc(victim, DISC_CELERITY) > 0 &&
IS_CLASS(victim, CLASS_VAMPIRE))
{
chance += 20;
chance += get_disc(victim, DISC_CELERITY) * 2;
}
}
/* Gift of Spragins:) */
if (IS_ADDED(victim,ADDED_ENLARGE))
chance += GS_DODGEBON;
if (IS_ADDED(victim,ADDED_SHRINK))
chance -= GS_DODGEBON;
if (!IS_NPC(ch) && get_disc(ch, DISC_CELERITY) > 0 &&
IS_CLASS(ch, CLASS_VAMPIRE))
{ // 8,5,2
if (ch->pcdata->rank == AGE_METHUSELAH) chance -= 5;
else if (ch->pcdata->rank == AGE_ELDER) chance -= 3;
else if (ch->pcdata->rank == AGE_ANCILLA) chance -= 1;
}
if (!IS_NPC(victim) && get_disc(victim, DISC_CELERITY) > 0 &&
IS_CLASS(victim, CLASS_VAMPIRE))
{
if (victim->pcdata->rank == AGE_METHUSELAH) chance += 5;
else if (victim->pcdata->rank == AGE_ELDER) chance += 3;
else if (victim->pcdata->rank == AGE_ANCILLA) chance += 1;
}
if (!IS_NPC(victim) && IS_SWWF(victim))
{
switch ( victim->pcdata->wwf_shape )
{
case SHAPE_GLABRO:
chance += number_range(3,11);
break;
case SHAPE_CRINOS:
chance += number_range(12,18);
break;
case SHAPE_HISPO:
chance += number_range(7,18);
break;
case SHAPE_LUPUS:
chance += number_range(3,10);
break;
}
if (get_tribe(ch,TRIBE_SILENT_STRIDERS) > 4)
{
chance += number_range(3,8);
}
}
if (chance > 75) chance = 75;
else if (chance < 25) chance = 25;
roll_a = number_percent( );
roll_b = number_percent( );
// If the Chance is Lower then the Roll then doge has failed..
if ( roll_a < 100 && roll_b >= chance )
return FALSE;
sprintf(buf,"@%s#%s^Dodge:(%d) Chance:(%d)",ch->name->str,victim->name->str,roll_b,chance);
show_fm(ch,buf);
if (IS_NPC(victim) || !IS_SET(victim->act, PLR_BRIEF))
act( "You dodge $n's attack.", ch, NULL, victim, TO_VICT );
if (IS_NPC(ch) || !IS_SET(ch->act, PLR_BRIEF))
act( "$N dodges your attack.", ch, NULL, victim, TO_CHAR );
act( "$N dodges $n attack.", ch, NULL, victim, TO_NOTVICTBR );
return TRUE;
}
/*
* Set position of a victim.
*/
void update_pos( CHAR_DATA *victim )
{
CHAR_DATA *mount;
if ( victim->hit > 0 )
{
if ( victim->position <= POS_STUNNED )
{
bool gm_stance = FALSE;
victim->position = POS_STANDING;
if (!IS_NPC(victim) && victim->stance[0] > 0)
{
int stance = victim->stance[0];
if (victim->stance[stance] >= 200) gm_stance = TRUE;
}
if (IS_NPC(victim) || victim->max_hit * 0.25 > victim->hit ||
!gm_stance)
{
act( "$n clambers back to $s feet.", victim, NULL, NULL, TO_ROOM);
act( "You clamber back to your feet.", victim, NULL, NULL, TO_CHAR);
}
else
{
act( "$n flips back up to $s feet.", victim, NULL, NULL, TO_ROOM);
act( "You flip back up to your feet.", victim, NULL, NULL, TO_CHAR);
}
}
return;
}
else if ( (mount = victim->mount) != NULL)
{
if (victim->mounted == IS_MOUNT)
{
act("$n rolls off $N.",mount,NULL,victim,TO_ROOM);
act("You roll off $N.",mount,NULL,victim,TO_CHAR);
}
else if (victim->mounted == IS_RIDING)
{
act("$n falls off $N.",victim,NULL,mount,TO_ROOM);
act("You fall off $N.",victim,NULL,mount,TO_CHAR);
}
mount->mount = NULL;
victim->mount = NULL;
mount->mounted = IS_ON_FOOT;
victim->mounted = IS_ON_FOOT;
}
if (!IS_NPC(victim) && victim->hit <=-11 && IS_HERO(victim))
{
victim->hit = -10;
if (victim->position == POS_FIGHTING)
stop_fighting(victim,TRUE);
return;
}
if ( IS_NPC(victim) || 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[MSL]; // For show fight...
//char buf2[MSL];
//int sn;
if (HAS_DELAY(ch))
return;
if ( ch->fighting != NULL )
{
bug( "Set_fighting: already fighting", 0 );
abort();
return;
}
if ( check_safe_imm(ch) )
{
if (ch->position == POS_FIGHTING || ch->fighting != NULL)
stop_fighting(ch,TRUE);
if (victim->position == POS_FIGHTING || victim->fighting != NULL)
stop_fighting(ch,TRUE);
return;
}
if ( ch->in_room != NULL && IS_RAFFECTED(ch->in_room,ROOM_AFF_REINA))
return;
if ( IS_AFFECTED(ch, AFF_SLEEP) )
affect_strip( ch, gsn_sleep );
ch->fighting = victim;
ch->position = POS_FIGHTING;
ch->damcap[DAM_CHANGE] = 1;
if (IS_NPC(victim) && !IS_NPC(ch))
{
set_mob_stance(victim);
mob_remember(victim,ch,MEM_HOSTILE);
}
if (!IS_NPC(ch) && !IS_NPC(victim) && ch != victim)
{
ch->pk_timer = 8;
victim->pk_timer = 8;
if (IS_SET(ch->act,ACT_TAPPING))
{
if (IS_CLASS(ch,CLASS_MAGE))
{
REMOVE_BIT(ch->act,ACT_TAPPING);
send_to_char("You connot tap and fight at the same time!\n\r",victim);
}
}
if (IS_SET(victim->act,ACT_TAPPING))
{
if (IS_CLASS(victim,CLASS_MAGE))
{
REMOVE_BIT(victim->act,ACT_TAPPING);
send_to_char("You connot tap and fight at the same time!\n\r",victim);
}
}
}
return;
}
/*
* Stop fights.
*/
void stop_fighting( CHAR_DATA *ch, bool fBoth )
{
CHAR_DATA *fch;
char buf[MSL];
if ( char_list == NULL )
return;
if (ch->fighting != NULL){
sprintf(buf,"@%s#%s^STOP FIGHTING",ch->name->str,ch->fighting->name->str);
show_fm(ch,buf);
}
for ( fch = char_list; fch != NULL; fch = fch->next )
{
if ( fch == ch || ( fBoth && fch->fighting == ch ) )
{
fch->fighting = NULL;
fch->position = POS_STANDING;
update_pos( fch );
}
}
if (IS_SWWF(ch) && IS_ADDED(ch,ADDED_FRENZY))
{
send_to_char("Your garou frenzy subsides.\n\r",ch);
REMOVE_BIT(ch->added,ADDED_FRENZY);
}
mudsetting->last_proc_logged = 45;
return;
}
void show_spirit_rise(CHAR_DATA *ch){
CHAR_DATA *victim;
for (victim = ch->in_room->people; victim != NULL; victim = victim->next_in_room){
if (IS_ADDED(victim, ADDED_SPIRIT_SIGHT)){
send_to_char("What look like steam rising off the body, a restless spirit rises to this world.\n\r",victim);
}
}
}
/*
* Make a Spirit of the Desceased Vicitm..
*/
void make_spirit( CHAR_DATA *ch){
CHAR_DATA *spirit;
spirit = create_mobile(get_mob_index(MOB_VNUM_RESTLESS_SPIRIT));
spirit->level = ch->level / 10;
spirit->max_hit = ch->max_hit / 10;
spirit->mana = ch->mana / 10;
show_spirit_rise(ch);
spirit->plane = PLANE_SPIRIT;
if (20 < number_range(1,100))
SET_BIT(spirit->mob_con, MOBCON_PISSED_SPIRIT);
else
SET_BIT(spirit->mob_con, MOBCON_NICE_SPIRIT);
char_to_room(spirit,ch->in_room);
}
/*
* Make a corpse out of a character.
*/
void make_corpse( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *corpse;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
int plane;
char *name;
if (ch->plane == PLANE_DEAD)
plane = PLANE_NORMAL;
else
plane = ch->plane;
if ( IS_NPC(ch) )
{
name = ch->short_descr->str;
corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_NPC), 0);
corpse->timer = number_range( 2, 5 );
corpse->value[2]= ch->pIndexData->vnum;
if ( ch->pIndexData->pShop == NULL )
{
if ( ch->gold > 0 )
{
obj_to_obj( create_money( ch->gold ), corpse );
ch->gold = 0;
}
}
/*filets*/
if (IS_SET(ch->act, ACT_ANIMAL))
{
SET_BIT(corpse->extra_flags,ITEM_FILET);
}
}
else
{
name = ch->name->str;
corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0);
corpse->timer = number_range( 25, 40 );
/* Why should players keep their gold? */
if ( ch->gold > 0 )
{
obj = create_money( ch->gold );
obj->plane = ch->plane;
obj_to_obj( obj, corpse );
ch->gold = 0;
}
}
sprintf( buf, corpse->short_descr->str, name );
corpse->short_descr = g_string_assign(corpse->short_descr, buf );
sprintf( buf, corpse->description->str, name );
corpse->description = g_string_assign(corpse->description, buf );
if (ch->killed_by != NULL)
{
corpse->questmaker = g_string_assign(corpse->questmaker,ch->killed_by->name->str);
ch->killed_by = NULL;
}
corpse->questowner = g_string_assign(corpse->questowner,ch->name->str);
for ( obj = ch->carrying; obj != NULL; obj = obj_next )
{
obj_next = obj->next_content;
obj_from_char( obj );
if ( IS_SET( obj->extra_flags, ITEM_VANISH ) )
extract_obj( obj );
else{
obj->plane = ch->plane;
obj_to_obj(obj,corpse);
}
}
corpse->plane = ch->plane;
if (ch->in_room == NULL)
bug("Make_Corpse: Ch not in Room",0);
obj_to_room( corpse, ch->in_room );
return;
}
void death_cry( CHAR_DATA *ch )
{
ROOM_INDEX_DATA *was_in_room;
char *msg;
int door;
if ( IS_NPC(ch) )
msg = "You hear something's death cry.";
else
msg = "You hear someone's death cry.";
if ( ch->in_room == NULL )
return;
was_in_room = ch->in_room;
for ( door = 0; door <= 5; door++ )
{
EXIT_DATA *pexit;
if ( ( pexit = was_in_room->exit[door] ) != NULL
&& pexit->to_room != NULL
&& pexit->to_room != was_in_room )
{
ch->in_room = pexit->to_room;
act( msg, ch, NULL, NULL, TO_ROOM );
}
}
ch->in_room = was_in_room;
return;
}
void make_part( CHAR_DATA *ch, char *argument )
{
char arg [MAX_INPUT_LENGTH];
int vnum;
argument = one_argument(argument,arg);
vnum = 0;
if (IS_SET(ch->sphere_spaffect, AFSPHERE_MANA_SHIELD))
return;
if (arg[0] == '\0') return;
if (!str_cmp(arg,"head")) vnum = OBJ_VNUM_SEVERED_HEAD;
else if (!str_cmp(arg,"arm")) vnum = OBJ_VNUM_SLICED_ARM;
else if (!str_cmp(arg,"leg")) vnum = OBJ_VNUM_SLICED_LEG;
else if (!str_cmp(arg,"heart")) vnum = OBJ_VNUM_TORN_HEART;
else if (!str_cmp(arg,"turd")) vnum = OBJ_VNUM_TORN_HEART;
else if (!str_cmp(arg,"entrails")) vnum = OBJ_VNUM_SPILLED_ENTRAILS;
else if (!str_cmp(arg,"brain")) vnum = OBJ_VNUM_QUIVERING_BRAIN;
else if (!str_cmp(arg,"eyeball")) vnum = OBJ_VNUM_SQUIDGY_EYEBALL;
else if (!str_cmp(arg,"blood")) vnum = OBJ_VNUM_SPILT_BLOOD;
else if (!str_cmp(arg,"face")) vnum = OBJ_VNUM_RIPPED_FACE;
else if (!str_cmp(arg,"windpipe")) vnum = OBJ_VNUM_TORN_WINDPIPE;
else if (!str_cmp(arg,"cracked_head")) vnum = OBJ_VNUM_CRACKED_HEAD;
else if (!str_cmp(arg,"ear")) vnum = OBJ_VNUM_SLICED_EAR;
else if (!str_cmp(arg,"nose")) vnum = OBJ_VNUM_SLICED_NOSE;
else if (!str_cmp(arg,"tooth")) vnum = OBJ_VNUM_KNOCKED_TOOTH;
else if (!str_cmp(arg,"tongue")) vnum = OBJ_VNUM_TORN_TONGUE;
else if (!str_cmp(arg,"hand")) vnum = OBJ_VNUM_SEVERED_HAND;
else if (!str_cmp(arg,"foot")) vnum = OBJ_VNUM_SEVERED_FOOT;
else if (!str_cmp(arg,"thumb")) vnum = OBJ_VNUM_SEVERED_THUMB;
else if (!str_cmp(arg,"index")) vnum = OBJ_VNUM_SEVERED_INDEX;
else if (!str_cmp(arg,"middle")) vnum = OBJ_VNUM_SEVERED_MIDDLE;
else if (!str_cmp(arg,"ring")) vnum = OBJ_VNUM_SEVERED_RING;
else if (!str_cmp(arg,"little")) vnum = OBJ_VNUM_SEVERED_LITTLE;
else if (!str_cmp(arg,"toe")) vnum = OBJ_VNUM_SEVERED_TOE;
if ( vnum != 0 )
{
GString *buf;
OBJ_DATA *obj;
GString *name;
buf = g_string_new("");
name = g_string_new("");
if (IS_NPC(ch))
name = g_string_assign(name,ch->short_descr->str);
else
name = g_string_assign(name,ch->name->str);
obj = create_object( get_obj_index( vnum ), 0 );
if (IS_NPC(ch)) obj->timer = number_range(1,3);
else obj->timer = number_range(1,5);
if (!str_cmp(arg,"head") && IS_NPC(ch))
obj->value[1] = ch->pIndexData->vnum;
else if (!str_cmp(arg,"head") && !IS_NPC(ch))
{ch->pcdata->chobj = obj; obj->chobj = ch;obj->timer = number_range(2,3);}
else if (!str_cmp(arg,"brain") && !IS_NPC(ch) &&
IS_AFFECTED(ch,AFF_POLYMORPH) && IS_HEAD(ch, LOST_HEAD))
{
if (ch->pcdata->chobj != NULL) ch->pcdata->chobj->chobj = NULL;
ch->pcdata->chobj = obj;
obj->chobj = ch;
obj->timer = number_range(2,3);
}
/* For blood :) KaVir */
if (vnum == OBJ_VNUM_SPILT_BLOOD) obj->timer = 2;
/* For voodoo dolls - KaVir */
if (!IS_NPC(ch))
{
g_string_sprintf( buf, obj->name->str, name->str );
obj->name = g_string_assign(obj->name, buf->str );
}
else
{
g_string_sprintf( buf, obj->name->str, "mob" );
obj->name = g_string_assign(obj->name, buf->str );
}
g_string_sprintf( buf, obj->short_descr->str, name->str );
obj->short_descr = g_string_assign(obj->short_descr, buf->str );
g_string_sprintf( buf, obj->description->str, name->str );
obj->description = g_string_assign(obj->description, buf->str );
if (str_cmp(arg,"blood")) obj->item_type = ITEM_TRASH;
obj->plane = ch->plane;
obj_to_room( obj, ch->in_room );
g_string_free(buf, TRUE);
g_string_free(name,TRUE);
}
return;
}
void raw_kill( CHAR_DATA *victim )
{
CHAR_DATA *mount;
stop_fighting( victim, TRUE );
death_cry( victim );
if (IS_SWWF(victim))
shape_shift(victim, SHAPE_HOMID);
make_corpse( victim );
if ( (mount = victim->mount) != NULL)
{
if (victim->mounted == IS_MOUNT)
{
act("$n rolls off the corpse of $N.",mount,NULL,victim,TO_ROOM);
act("You roll off the corpse of $N.",mount,NULL,victim,TO_CHAR);
}
else if (victim->mounted == IS_RIDING)
{
act("$n falls off $N.",victim,NULL,mount,TO_ROOM);
act("You fall off $N.",victim,NULL,mount,TO_CHAR);
}
mount->mount = NULL;
victim->mount = NULL;
mount->mounted = IS_ON_FOOT;
victim->mounted = IS_ON_FOOT;
}
/*
* If they are HARDCORE! they should be given the chance to Wraith!
* if not delete thier ass!
*/
if (!IS_NPC(victim) && victim->level > 1 && IS_SET(victim->added,ADDED_HARDCORE)){
victim->plane = PLANE_DEAD;
send_to_char("Well look like you have died.\n\r",victim);
send_to_char("You have the chance to become a wraith at this point.\n\r",victim);
send_to_char("If you wish to Die, and be deleted please type {RKILLME{x\n\r",victim);
send_to_char("If you wish to become a {WWraith{x please type {RWRAITH{x\n\r",victim);
send_to_char("Please type help becoming-wraith for more help.\n\r",victim);
return;
}
if ( IS_NPC(victim) && !IS_PET(victim) )
{
victim->pIndexData->killed++;
kill_table[URANGE(0, victim->level, MAX_LEVEL-1)].killed++;
extract_char( victim, TRUE );
return;
}
if (IS_PET(victim))
victim->pet_stats[PET_PERM_AFF] -= 20;
extract_char( victim, FALSE );
while ( victim->affected )
affect_remove( victim, victim->affected );
while ( victim->sphere_affected )
sphere_remove( victim, victim->sphere_affected );
if (IS_AFFECTED(victim,AFF_POLYMORPH))
{
victim->affected_by = AFF_POLYMORPH;
}
else if (IS_AFFECTED(victim,AFF_POLYMORPH))
victim->affected_by = AFF_POLYMORPH;
else
victim->affected_by = 0;
REMOVE_BIT(victim->immune, IMM_STAKE);
REMOVE_BIT(victim->extra, TIED_UP);
REMOVE_BIT(victim->extra, GAGGED);
REMOVE_BIT(victim->extra, BLINDFOLDED);
REMOVE_BIT(victim->extra, EXTRA_PREGNANT);
REMOVE_BIT(victim->extra, EXTRA_LABOUR);
victim->itemaffect = 0;
victim->loc_hp[0] = 0;
victim->loc_hp[1] = 0;
victim->loc_hp[2] = 0;
victim->loc_hp[3] = 0;
victim->loc_hp[4] = 0;
victim->loc_hp[5] = 0;
victim->loc_hp[6] = 0;
victim->blood_count = 0;
victim->armor = 100;
victim->position = POS_RESTING;
victim->hit = UMAX( 1, victim->hit );
victim->mana = UMAX( 1, victim->mana );
victim->move = UMAX( 1, victim->move );
victim->hitroll = 0;
victim->damroll = 0;
victim->saving_throw = 0;
victim->carry_weight = 0;
victim->carry_number = 0;
if (IS_SET(victim->act,PLR_ATTACK))
{
victim->pk_sect = 0;
REMOVE_BIT(victim->act, PLR_ATTACK);
}
if (!IS_PET(victim))
{
do_call(victim,"all");
save_char_obj( victim );
}
return;
}
void behead( CHAR_DATA *victim )
{
char buf [MAX_STRING_LENGTH];
ROOM_INDEX_DATA *location;
if (IS_NPC(victim)) return;
location = victim->in_room;
stop_fighting( victim, TRUE );
make_corpse( victim );
extract_char( victim, FALSE );
char_from_room(victim);
char_to_room(victim,location);
if (victim == NULL)
{bug( "Behead: Victim no longer exists.", 0 );return;}
make_part( victim, "head" );
while ( victim->affected )
affect_remove( victim, victim->affected );
if (IS_AFFECTED(victim,AFF_POLYMORPH))
{
victim->affected_by = AFF_POLYMORPH;
}
else if (IS_AFFECTED(victim,AFF_POLYMORPH))
victim->affected_by = AFF_POLYMORPH;
else
victim->affected_by = 0;
if ( victim->hit - victim->pcdata->absorb[ABS_MOB_HP] >= 1 ||
victim->max_hit - victim->pcdata->absorb[ABS_MOB_MAX_HP] >= 1 )
{
victim->hit -= victim->pcdata->absorb[ABS_MOB_HP];
victim->max_hit -= victim->pcdata->absorb[ABS_MOB_MAX_HP];
victim->pcdata->absorb[ABS_MOB_VNUM] = 0;
victim->pcdata->absorb[ABS_MOB_HP] = 0;
victim->pcdata->absorb[ABS_MOB_MAX_HP] = 0;
}
REMOVE_BIT(victim->immune, IMM_STAKE);
REMOVE_BIT(victim->extra, TIED_UP);
REMOVE_BIT(victim->extra, GAGGED);
REMOVE_BIT(victim->extra, BLINDFOLDED);
REMOVE_BIT(victim->extra, EXTRA_PREGNANT);
REMOVE_BIT(victim->extra, EXTRA_LABOUR);
victim->itemaffect = 0;
victim->loc_hp[0] = 0;
victim->loc_hp[1] = 0;
victim->loc_hp[2] = 0;
victim->loc_hp[3] = 0;
victim->loc_hp[4] = 0;
victim->loc_hp[5] = 0;
victim->loc_hp[6] = 0;
victim->affected_by = 0;
victim->armor = 100;
victim->position = POS_STANDING;
victim->hit = 1;
victim->mana = UMAX( 1, victim->mana );
victim->move = UMAX( 1, victim->move );
victim->hitroll = 0;
victim->damroll = 0;
victim->saving_throw = 0;
victim->carry_weight = 0;
victim->carry_number = 0;
if (IS_SWWF(victim))
shape_shift(victim, SHAPE_HOMID);
SET_BIT(victim->loc_hp[0],LOST_HEAD);
SET_BIT(victim->affected_by,AFF_POLYMORPH);
sprintf(buf,"the severed head of %s",victim->name->str);
victim->morph = g_string_assign(victim->morph, buf);
//do_call(victim,"all");
save_char_obj( victim );
return;
}
void group_gain( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *gch;
CHAR_DATA *lch;
CHAR_DATA *mount;
int xp;
int random_int;
int members;
if (IS_SET(ch->act, PLR_QUESTOR)&&IS_NPC(victim))
{
if (ch->questmob == victim->pIndexData->vnum)
{
send_to_char("You have almost completed your QUEST!\n\r",ch);
send_to_char("Return to the questmaster before your time runs out!\n\r",ch);
ch->questmob = -1;
}
}
//No exp for pets... Lamers
if (IS_PET(victim))
return;
/*
* Monsters don't get kill xp's or alignment changes.
* Dying of mortal wounds or poison doesn't give xp to anyone!
* Altered to allow "pets" to get exp to increase thier Hp's etc
*/
if ( (IS_NPC(ch) && !IS_PET(ch) && (mount = ch->mount) == NULL) || victim == ch )
return;
members = 0;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( is_same_group( gch, ch ) )
members++;
}
if ( members == 0 )
{
bug( "Group_gain: members.", members );
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;
if ( !is_same_group( gch, ch ) )
continue;
if ( !is_same_plane( gch, ch ) )
continue;
xp = xp_compute( gch, victim ) / members;
xp += (xp * (ch->race) / 7);
/* Grin from Dominion gives 10*xp as a bonus. */
random_int = 1+(int) (75.0*rand()/(RAND_MAX+1.0));
if (random_int == 50.0)
{
xp *= 2;
sprintf( buf, "{MPuff snickers about you gaining {R%d{M experience points.{x\n\r", xp);
send_to_char( buf, gch );
}
else if (random_int == 45.0)
{
xp *= 7;
sprintf( buf, "{YAslan scowls angrilly at you gaining {R%d{M experience points.{x\n\r", xp);
send_to_char( buf, gch );
}
else if (random_int == 30.0)
{
xp *= 7;
sprintf( buf, "{GSpiral rolls on the floor laughing at you, you gain {R%d{C experience points.{x\n\r", xp);
send_to_char( buf, gch );
}
else
{
sprintf( buf, "{YYou receive {W%d{Y experience points.{x\n\r", xp );
send_to_char( buf, gch );
}
if ((mount = gch->mount) != NULL) send_to_char( buf, mount );
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_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) ) )
{
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 align;
int xp;
int extra;
int level;
int number;
int vnum;
int victim_level; /* put to stop mass exp give outs Rotain */
xp = 300 - URANGE( -3, 3 - victim->level, 6 ) * 50;
align = gch->alignment - victim->alignment;
if (victim->level > 1000 )
victim_level = 1000;
else
victim_level = victim->level;
if (IS_HERO(gch))
{
/* Avatars shouldn't be able to change their alignment */
gch->alignment = gch->alignment;
}
else if ( align > 500 )
{
gch->alignment = UMIN( gch->alignment + (align-500)/4, 1000 );
xp = 5 * xp / 4;
}
else if ( align < -500 )
{
gch->alignment = UMAX( gch->alignment + (align+500)/4, -1000 );
}
else
{
gch->alignment -= gch->alignment / 4;
xp = 3 * xp / 4;
}
/*
* Put in mob vnum that you don't want players to gain exp for
* Rotain
*/
if (IS_NPC(victim) && (vnum = victim->pIndexData->vnum) > 29000)
{
switch (vnum)
{
default:
break;
case 29600:
case 30001:
case 30006:
case 30007:
case 30008:
case 30009:
case 30000:
return 0;
}
}
if (IS_NPC(victim) && (IS_SET(victim->act, ACT_NOEXP) || IS_IMMORTAL(gch)))
return 0;
/*
* Adjust for popularity of target:
* -1/8 for each target over 'par' (down to -100%)
* +1/8 for each target under 'par' ( up to + 25%)
*/
level = URANGE( 0, victim_level, MAX_LEVEL - 1 );
number = UMAX( 1, kill_table[level].number );
extra = victim->pIndexData->killed - kill_table[level].killed / number;
/* xp -= xp * URANGE( -2, extra, 8 ) / 8;
xp -= xp * URANGE( -2, extra, 6 ) / 8; */
xp -= xp * number_range( -2, 2 ) / 8;
xp = number_range( xp * 3 / 4, xp * 5 / 4 );
xp = UMAX( 0, xp );
xp = (xp * (int)((double)(victim_level+1) * 0.25));
return xp;
}
void dam_message( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt )
{
char buf1[512], buf2[512], buf3[512];
const char *vs;
const char *vp;
const char *attack;
const char *attack2;
int damp;
int bodyloc;
bool critical = FALSE;
char punct;
if ( dam == 0 ) { vs = " {Ymiss{x";
vp = " {Ymisses{x";}
else if ( dam <= 25 ) { vs = " {Ylightly{x";
vp = " {Ylightly{x";}
else if ( dam <= 50 ) { vs = " {Yless hard{x";
vp = " {Yhardly{x";}
else if ( dam <= 100 ) { vs = " {mhard{x";
vp = " {mhard{x";}
else if ( dam <= 250 ) { vs = " {mvery hard{x";
vp = " {mvery hard{x"; }
else if ( dam <= 500 ) { vs = " {mextremely hard{x";
vp = " {mextremely hard{x";}
else if ( dam <= 750 ) { vs = " {msavagely hard{x";
vp = " {msavagely hard{x";}
else if ( dam <= 1000) { vs = " {rsavagely hard{x";
vp = " {rsavagely hard{x";}
else if ( dam <= 1250) { vs = " {rincredibly hard{x";
vp = " {rincredibly hard{x";}
else if ( dam <= 1500) { vs = " {rincredibly hard{x";
vp = " {rincredibly hard{x";}
else if ( dam <= 1750) { vs = " {rimpressively hard{x";
vp = " {rimpressively hard{x";}
else if ( dam <= 2000) { vs = " {Rimpressively hard{x";
vp = " {Rimpressively hard{x";}
else if ( dam <= 2250) { vs = " {Ramazingly hard{x";
vp = " {Ramazingly hard{x";}
else if ( dam <= 2500) { vs = " {Runbelievably hard{x";
vp = " {Runbelievably hard{x";}
else if ( dam <= 2750) { vs = " {Rastoundingly hard{x";
vp = " {Rastoundingly hard{x";}
else if ( dam <= 3000) { vs = " {Mastoundingly hard{x";
vp = " {Mastoundingly hard{x";}
else if ( dam <= 3500) { vs = " {Mastonishingly hard{x";
vp = " {Mastonishingly hard{x";}
else if ( dam <= 4000) { vs = " {Mextraordinarily hard{x";
vp = " {Mextraordinarily hard{x";}
else if ( dam <= 4500) { vs = " {Mbreathtakingly hard{x";
vp = " {Mbreathtakingly hard{x";}
else if ( dam <= 5500) { vs = " {WUNSPEAKABLY hard{x";
vp = " {WUNSPEAKABLY hard{x";}
else { vs = " {Wtoo HARD to comprehend{x";
vp = " {Wtoo HARD to comprehend{x";}
/* If victim's hp are less/equal to 'damp', attacker gets a death blow */
if (IS_NPC(victim)) damp = 0;
else damp = -10;
//Show the confuse message - Spiral
if ( ch == victim && !IS_ADDED(ch, ADDED_CONFUSE))
{
send_to_char("You hit your self hard!\n\r",ch);
act("$n just hit themself hard!\n\r",ch,NULL,NULL,TO_NOTVICT);
return;
}
else if ( ch == victim && IS_ADDED(ch,ADDED_CONFUSE))
{
send_to_char("In your confusion you hit your opponent real hard, to bad it was yourself!\n\r",ch);
act("Confused, $n pulls back and nails $n!",ch,NULL,NULL, TO_NOTVICT);
return;
}
if ( (victim->hit - dam > damp ) || (dt >= 0 && dt < MAX_SKILL) ||
(IS_NPC(victim) && IS_SET(victim->act, ACT_NOPARTS)) )
{
punct = (dam <= 250) ? '.' : '!';
if ( dt == TYPE_HIT && !IS_NPC(ch) && !IS_VAMPAFF(ch,VAM_CLAWS) )
{
if (dam == 0)
{
sprintf( buf1, "{x$n%s $N%c", vp, punct );
sprintf( buf2, "{xYou%s $N%c", vs, punct );
sprintf( buf3, "{x$n%s you%c", vp, punct );
}
else if (IS_SET(ch->act,PLR_AUTODAMAGE))
{
sprintf( buf1, "{x$n hits $N%s%c", vp, punct );
sprintf( buf2, "{xYou hit $N%s%c [{R%d{x]", vs, punct, dam );
sprintf( buf3, "{x$n hits you%s%c [{R%d{x]", vp, punct, dam );
critical = TRUE;
}
else
{
sprintf( buf1, "{x$n hits $N%s%c", vp, punct );
sprintf( buf2, "{xYou hit $N%s%c", vs, punct );
sprintf( buf3, "{x$n hits you%s%c", vp, punct );
critical = TRUE;
}
}
else
{
if ( dt == TYPE_HIT && !IS_NPC(ch) && IS_VAMPAFF(ch,VAM_CLAWS))
{
attack = damage_table[dt - TYPE_HIT + 5].attack1 ;
attack2 = damage_table[dt - TYPE_HIT + 5].attack2;
}
else if ( dt >= 0 && dt < MAX_SKILL )
{
attack = skill_table[dt].noun_damage;
attack2 = skill_table[dt].noun_damage;
}
else if ( dt >= TYPE_HIT
&& dt < TYPE_HIT + MAX_DAMAGE_TYPE )
{
attack = damage_table[dt - TYPE_HIT].attack1 ;
attack2 = damage_table[dt - TYPE_HIT].attack2;
}
else
{
bug( "Dam_message: bad dt %d.", dt );
dt = TYPE_HIT;
attack = damage_table[0].attack1;
attack2 = damage_table[0].attack2;
}
if (dam == 0)
{
sprintf( buf1, "{x$n's %s%s $N%c", attack, vp, punct );
sprintf( buf2, "{xYour %s%s $N%c", attack, vp, punct );
sprintf( buf3, "{x$n's %s%s you%c", attack, vp, punct );
}
else if (IS_SET(ch->act,PLR_AUTODAMAGE))
{
sprintf( buf1, "{x$n's %s strikes $N%s%c", attack, vp, punct );
sprintf( buf2, "{xYour %s strikes $N%s%c [%d]", attack, vs, punct, dam );
sprintf( buf3, "{x$n's %s strikes you%s%c [%d]", attack, vp, punct, dam );
critical = TRUE;
}
else
{
if ( dt >= 0 && dt < MAX_SKILL )
{
sprintf( buf1, "{x$n's %s strikes $N%s%c", attack2, vp, punct );
sprintf( buf2, "{xYour %s strikes $N%s%c", attack, vp, punct );
sprintf( buf3, "{x$n's %s strikes you%s%c", attack2, vp, punct );
}
else if (IS_SET(ch->act,PLR_AUTODAMAGE))
{
sprintf( buf1, "{x$n %s $N%s%c",attack2, vp, punct );
sprintf( buf2, "{xYou %s $N%s%c [%d]",attack, vs, punct, dam );
sprintf( buf3, "{x$n %s you%s%c [%d]",attack2, vp, punct, dam );
critical = TRUE;
}
else
{
sprintf( buf1, "{x$n %s $N%s%c", attack2, vp, punct );
sprintf( buf2, "{xYou %s $N%s%c", attack, vp, punct );
sprintf( buf3, "{x$n %s you%s%c", attack2, vp, punct );
critical = TRUE;
}
}
}
act( buf1, ch, NULL, victim, TO_NOTVICT );
act( buf2, ch, NULL, victim, TO_CHAR );
act( buf3, ch, NULL, victim, TO_VICT );
if (critical) critical_hit(ch,victim,dt,dam);
return;
}
if ( dt == TYPE_HIT && !IS_NPC( ch ) && !IS_VAMPAFF(ch,VAM_CLAWS)
&&!IS_VAMPAFF(ch,VAM_FANGS))
{
damp=number_range(1,5);
if ( damp == 1 )
{
act("You ram your fingers into $N's eye sockets and rip $S face off.", ch, NULL, victim, TO_CHAR);
act("$n rams $s fingers into $N's eye sockets and rips $S face off.", ch, NULL, victim, TO_NOTVICT);
act("$n rams $s fingers into your eye sockets and rips your face off.", ch, NULL, victim, TO_VICT);
make_part(victim,"face");
}
else if ( damp == 2 )
{
act("You grab $N by the throat and tear $S windpipe out.", ch, NULL, victim, TO_CHAR);
act("$n grabs $N by the throat and tears $S windpipe out.", ch, NULL, victim, TO_NOTVICT);
act("$n grabs you by the throat and tears your windpipe out.", ch, NULL, victim, TO_VICT);
make_part(victim,"windpipe");
}
else if ( damp == 3 )
{
act("You punch your fist through $N's stomach and rip out $S entrails.", ch, NULL, victim, TO_CHAR);
act("$n punches $s fist through $N's stomach and rips out $S entrails.", ch, NULL, victim, TO_NOTVICT);
act("$n punches $s fist through your stomach and rips out your entrails.", ch, NULL, victim, TO_VICT);
make_part(victim,"entrails");
}
else if ( damp == 4 )
{
if (!IS_BODY(victim,BROKEN_SPINE))
SET_BIT(victim->loc_hp[1],BROKEN_SPINE);
act("You hoist $N above your head and slam $M down upon your knee.\n\rThere is a loud cracking sound as $N's spine snaps.", ch, NULL, victim, TO_CHAR);
act("$n hoists $N above $s head and slams $M down upon $s knee.\n\rThere is a loud cracking sound as $N's spine snaps.", ch, NULL, victim, TO_NOTVICT);
act("$n hoists you above $s head and slams you down upon $s knee.\n\rThere is a loud cracking sound as your spine snaps.", ch, NULL, victim, TO_VICT);
}
else if ( damp == 5 )
{
act("You lock your arm around $N's head, and give it a vicious twist.", ch, NULL, victim, TO_CHAR);
act("$n locks $s arm around $N's head, and gives it a vicious twist.", ch, NULL, victim, TO_NOTVICT);
act("$n locks $s arm around your head, and gives it a vicious twist.", ch, NULL, victim, TO_VICT);
if (!IS_BODY(victim,BROKEN_NECK))
{
act("There is a loud snapping noise as your neck breaks.", victim, NULL, NULL, TO_CHAR);
act("There is a loud snapping noise as $n's neck breaks.", victim, NULL, NULL, TO_ROOM);
SET_BIT(victim->loc_hp[1],BROKEN_NECK);
}
}
return;
}
if ( dt == TYPE_SLASH || dt == TYPE_SLICE )
{
damp=number_range(1,8);
if ( damp == 1 )
{
act("You swing your blade in a low arc, rupturing $N's abdominal cavity.\n\r$S entrails spray out over a wide area.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade in a low arc, rupturing $N's abdominal cavity.\n\r$S entrails spray out over a wide area.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade in a low arc, rupturing your abdominal cavity.\n\rYour entrails spray out over a wide area.", ch, NULL, victim, TO_VICT);
make_part(victim,"entrails");
}
else if ( damp == 2 )
{
act("You thrust your blade into $N's mouth and twist it viciously.\n\rThe end of your blade bursts through the back of $S head.", ch, NULL, victim, TO_CHAR);
act("$n thrusts $s blade into $N's mouth and twists it viciously.\n\rThe end of the blade bursts through the back of $N's head.", ch, NULL, victim, TO_NOTVICT);
act("$n thrusts $s blade into your mouth and twists it viciously.\n\rYou feel the end of the blade burst through the back of your head.", ch, NULL, victim, TO_VICT);
}
else if ( damp == 3 )
{
if (!IS_BODY(victim,CUT_THROAT))
SET_BIT(victim->loc_hp[1],CUT_THROAT);
if (!IS_BLEEDING(victim,BLEEDING_THROAT))
SET_BIT(victim->loc_hp[6],BLEEDING_THROAT);
act("Your blow slices open $N's carotid artery, spraying blood everywhere.", ch, NULL, victim, TO_CHAR);
act("$n's blow slices open $N's carotid artery, spraying blood everywhere.", ch, NULL, victim, TO_NOTVICT);
act("$n's blow slices open your carotid artery, spraying blood everywhere.", ch, NULL, victim, TO_VICT);
make_part(victim,"blood");
}
else if ( damp == 4 )
{
if (!IS_BODY(victim,CUT_THROAT))
SET_BIT(victim->loc_hp[1],CUT_THROAT);
if (!IS_BLEEDING(victim,BLEEDING_THROAT))
SET_BIT(victim->loc_hp[6],BLEEDING_THROAT);
act("You swing your blade across $N's throat, showering the area with blood.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade across $N's throat, showering the area with blood.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade across your throat, showering the area with blood.", ch, NULL, victim, TO_VICT);
make_part(victim,"blood");
}
else if ( damp == 5 )
{
if (!IS_HEAD(victim,BROKEN_SKULL))
{
act("You swing your blade down upon $N's head, splitting it open.\n\r$N's brains pour out of $S forehead.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade down upon $N's head, splitting it open.\n\r$N's brains pour out of $S forehead.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade down upon your head, splitting it open.\n\rYour brains pour out of your forehead.", ch, NULL, victim, TO_VICT);
make_part(victim,"brain");
SET_BIT(victim->loc_hp[0],BROKEN_SKULL);
}
else
{
act("You plunge your blade deep into $N's chest.", ch, NULL, victim, TO_CHAR);
act("$n plunges $s blade deep into $N's chest.", ch, NULL, victim, TO_NOTVICT);
act("$n plunges $s blade deep into your chest.", ch, NULL, victim, TO_VICT);
}
}
else if ( damp == 6 )
{
act("You swing your blade between $N's legs, nearly splitting $M in half.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade between $N's legs, nearly splitting $M in half.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade between your legs, nearly splitting you in half.", ch, NULL, victim, TO_VICT);
}
else if ( damp == 7 )
{
if (!IS_ARM_L(victim,LOST_ARM))
{
act("You swing your blade in a wide arc, slicing off $N's arm.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade in a wide arc, slicing off $N's arm.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade in a wide arc, slicing off your arm.", ch, NULL, victim, TO_VICT);
make_part(victim,"arm");
SET_BIT(victim->loc_hp[2],LOST_ARM);
if (!IS_BLEEDING(victim,BLEEDING_ARM_L))
SET_BIT(victim->loc_hp[6],BLEEDING_ARM_L);
if (IS_BLEEDING(victim,BLEEDING_HAND_L))
REMOVE_BIT(victim->loc_hp[6],BLEEDING_HAND_L);
}
else if (!IS_ARM_R(victim,LOST_ARM))
{
act("You swing your blade in a wide arc, slicing off $N's arm.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade in a wide arc, slicing off $N's arm.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade in a wide arc, slicing off your arm.", ch, NULL, victim, TO_VICT);
make_part(victim,"arm");
SET_BIT(victim->loc_hp[3],LOST_ARM);
if (!IS_BLEEDING(victim,BLEEDING_ARM_R))
SET_BIT(victim->loc_hp[6],BLEEDING_ARM_R);
if (IS_BLEEDING(victim,BLEEDING_HAND_R))
REMOVE_BIT(victim->loc_hp[6],BLEEDING_HAND_R);
}
else
{
act("You plunge your blade deep into $N's chest.", ch, NULL, victim, TO_CHAR);
act("$n plunges $s blade deep into $N's chest.", ch, NULL, victim, TO_NOTVICT);
act("$n plunges $s blade deep into your chest.", ch, NULL, victim, TO_VICT);
}
}
else if ( damp == 8 )
{
if (!IS_LEG_L(victim,LOST_LEG))
{
act("You swing your blade in a low arc, slicing off $N's leg at the hip.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade in a low arc, slicing off $N's leg at the hip.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade in a wide arc, slicing off your leg at the hip.", ch, NULL, victim, TO_VICT);
make_part(victim,"leg");
SET_BIT(victim->loc_hp[4],LOST_LEG);
if (!IS_BLEEDING(victim,BLEEDING_LEG_L))
SET_BIT(victim->loc_hp[6],BLEEDING_LEG_L);
if (IS_BLEEDING(victim,BLEEDING_FOOT_L))
REMOVE_BIT(victim->loc_hp[6],BLEEDING_FOOT_L);
}
else if (!IS_LEG_R(victim,LOST_LEG))
{
act("You swing your blade in a low arc, slicing off $N's leg at the hip.", ch, NULL, victim, TO_CHAR);
act("$n swings $s blade in a low arc, slicing off $N's leg at the hip.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s blade in a wide arc, slicing off your leg at the hip.", ch, NULL, victim, TO_VICT);
make_part(victim,"leg");
SET_BIT(victim->loc_hp[5],LOST_LEG);
if (!IS_BLEEDING(victim,BLEEDING_LEG_R))
SET_BIT(victim->loc_hp[6],BLEEDING_LEG_R);
if (IS_BLEEDING(victim,BLEEDING_FOOT_R))
REMOVE_BIT(victim->loc_hp[6],BLEEDING_FOOT_R);
}
else
{
act("You plunge your blade deep into $N's chest.", ch, NULL, victim, TO_CHAR);
act("$n plunges $s blade deep into $N's chest.", ch, NULL, victim, TO_NOTVICT);
act("$n plunges $s blade deep into your chest.", ch, NULL, victim, TO_VICT);
}
}
}
else if ( dt == TYPE_STAB || dt == TYPE_PIERCE )
{
damp=number_range(1,5);
if ( damp == 1 )
{
act("You deftly invert your weapon and plunge it point first into $N's chest.\n\rA shower of blood sprays from the wound, showering the area.", ch, NULL, victim, TO_CHAR);
act("$n deftly inverts $s weapon and plunge it point first into $N's chest.\n\rA shower of blood sprays from the wound, showering the area.", ch, NULL, victim, TO_NOTVICT);
act("$n deftly inverts $s weapon and plunge it point first into your chest.\n\rA shower of blood sprays from the wound, showering the area.", ch, NULL, victim, TO_VICT);
make_part(victim,"blood");
}
else if ( damp == 2 )
{
act("You thrust your blade into $N's mouth and twist it viciously.\n\rThe end of your blade bursts through the back of $S head.", ch, NULL, victim, TO_CHAR);
act("$n thrusts $s blade into $N's mouth and twists it viciously.\n\rThe end of the blade bursts through the back of $N's head.", ch, NULL, victim, TO_NOTVICT);
act("$n thrusts $s blade into your mouth and twists it viciously.\n\rYou feel the end of the blade burst through the back of your head.", ch, NULL, victim, TO_VICT);
}
else if ( damp == 3 )
{
act("You thrust your weapon up under $N's jaw and through $S head.", ch, NULL, victim, TO_CHAR);
act("$n thrusts $s weapon up under $N's jaw and through $S head.", ch, NULL, victim, TO_NOTVICT);
act("$n thrusts $s weapon up under your jaw and through your head.", ch, NULL, victim, TO_VICT);
}
else if ( damp == 4 )
{
act("You ram your weapon through $N's body, pinning $M to the ground.", ch, NULL, victim, TO_CHAR);
act("$n rams $s weapon through $N's body, pinning $M to the ground.", ch, NULL, victim, TO_NOTVICT);
act("$n rams $s weapon through your body, pinning you to the ground.", ch, NULL, victim, TO_VICT);
}
else if ( damp == 5 )
{
act("You stab your weapon into $N's eye and out the back of $S head.", ch, NULL, victim, TO_CHAR);
act("$n stabs $s weapon into $N's eye and out the back of $S head.", ch, NULL, victim, TO_NOTVICT);
act("$n stabs $s weapon into your eye and out the back of your head.", ch, NULL, victim, TO_VICT);
if (!IS_HEAD(victim,LOST_EYE_L) && number_percent() < 50)
SET_BIT(victim->loc_hp[0],LOST_EYE_L);
else if (!IS_HEAD(victim,LOST_EYE_R))
SET_BIT(victim->loc_hp[0],LOST_EYE_R);
else if (!IS_HEAD(victim,LOST_EYE_L))
SET_BIT(victim->loc_hp[0],LOST_EYE_L);
}
}
else if ( dt == TYPE_BLAST || dt == TYPE_POUND || dt == TYPE_CRUSH || dt == TYPE_HIT )
{
damp=number_range(1,3);
bodyloc = 0;
if ( damp == 1)
{
act("Your blow smashes through $N's chest, caving in half $S ribcage.", ch, NULL, victim, TO_CHAR);
act("$n's blow smashes through $N's chest, caving in half $S ribcage.", ch, NULL, victim, TO_NOTVICT);
act("$n's blow smashes through your chest, caving in half your ribcage.", ch, NULL, victim, TO_VICT);
if (IS_BODY(victim,BROKEN_RIBS_1 )) {bodyloc += 1;
REMOVE_BIT(victim->loc_hp[1],BROKEN_RIBS_1);}
if (IS_BODY(victim,BROKEN_RIBS_2 )) {bodyloc += 2;
REMOVE_BIT(victim->loc_hp[1],BROKEN_RIBS_2);}
if (IS_BODY(victim,BROKEN_RIBS_4 )) {bodyloc += 4;
REMOVE_BIT(victim->loc_hp[1],BROKEN_RIBS_4);}
if (IS_BODY(victim,BROKEN_RIBS_8 )) {bodyloc += 8;
REMOVE_BIT(victim->loc_hp[1],BROKEN_RIBS_8);}
if (IS_BODY(victim,BROKEN_RIBS_16)) {bodyloc += 16;
REMOVE_BIT(victim->loc_hp[1],BROKEN_RIBS_16);}
bodyloc += number_range(1,3);
if (bodyloc > 24) bodyloc = 24;
if (bodyloc >= 16) {bodyloc -= 16;
SET_BIT(victim->loc_hp[1],BROKEN_RIBS_16);}
if (bodyloc >= 8) {bodyloc -= 8;
SET_BIT(victim->loc_hp[1],BROKEN_RIBS_8);}
if (bodyloc >= 4) {bodyloc -= 4;
SET_BIT(victim->loc_hp[1],BROKEN_RIBS_4);}
if (bodyloc >= 2) {bodyloc -= 2;
SET_BIT(victim->loc_hp[1],BROKEN_RIBS_2);}
if (bodyloc >= 1) {bodyloc -= 1;
SET_BIT(victim->loc_hp[1],BROKEN_RIBS_1);}
}
else if ( damp == 2)
{
act("Your blow smashes $N's spine, shattering it in several places.", ch, NULL, victim, TO_CHAR);
act("$n's blow smashes $N's spine, shattering it in several places.", ch, NULL, victim, TO_NOTVICT);
act("$n's blow smashes your spine, shattering it in several places.", ch, NULL, victim, TO_VICT);
if (!IS_BODY(victim,BROKEN_SPINE))
SET_BIT(victim->loc_hp[1],BROKEN_SPINE);
}
else if ( damp == 3)
{
if (!IS_HEAD(victim,BROKEN_SKULL))
{
act("You swing your weapon down upon $N's head.\n\r$N's head cracks open like an overripe melon, leaking out brains.", ch, NULL, victim, TO_CHAR);
act("$n swings $s weapon down upon $N's head.\n\r$N's head cracks open like an overripe melon, covering you with brains.", ch, NULL, victim, TO_NOTVICT);
act("$n swings $s weapon down upon your head.\n\rYour head cracks open like an overripe melon, spilling your brains everywhere.", ch, NULL, victim, TO_VICT);
make_part(victim,"brain");
SET_BIT(victim->loc_hp[0],BROKEN_SKULL);
}
else
{
act("You hammer your weapon into $N's side, crushing bone.", ch, NULL, victim, TO_CHAR);
act("$n hammers $s weapon into $N's side, crushing bone.", ch, NULL, victim, TO_NOTVICT);
act("$n hammers $s weapon into your side, crushing bone.", ch, NULL, victim, TO_VICT);
}
}
}
else if ( !IS_NPC( ch ) && (dt == TYPE_BITE ||IS_VAMPAFF(ch,VAM_FANGS)))
{
act("You sink your teeth into $N's throat and tear out $S jugular vein.\n\rYou wipe the blood from your chin with one hand.", ch, NULL, victim, TO_CHAR);
act("$n sink $s teeth into $N's throat and tears out $S jugular vein.\n\r$n wipes the blood from $s chin with one hand.", ch, NULL, victim, TO_NOTVICT);
act("$n sink $s teeth into your throat and tears out your jugular vein.\n\r$n wipes the blood from $s chin with one hand.", ch, NULL, victim, TO_VICT);
make_part(victim,"blood");
if (!IS_BODY(victim,CUT_THROAT))
SET_BIT(victim->loc_hp[1],CUT_THROAT);
if (!IS_BLEEDING(victim,BLEEDING_THROAT))
SET_BIT(victim->loc_hp[6],BLEEDING_THROAT);
}
else if ( dt == TYPE_BITE )
{
act("You sink your teeth into $N's throat and tear out $S jugular vein.\n\rYou wipe the blood from your chin with one hand.", ch, NULL, victim, TO_CHAR);
act("$n sink $s teeth into $N's throat and tears out $S jugular vein.\n\r$n wipes the blood from $s chin with one hand.", ch, NULL, victim, TO_NOTVICT);
act("$n sink $s teeth into your throat and tears out your jugular vein.\n\r$n wipes the blood from $s chin with one hand.", ch, NULL, victim, TO_VICT);
make_part(victim,"blood");
if (!IS_BODY(victim,CUT_THROAT))
SET_BIT(victim->loc_hp[1],CUT_THROAT);
if (!IS_BLEEDING(victim,BLEEDING_THROAT))
SET_BIT(victim->loc_hp[6],BLEEDING_THROAT);
}
else if ( !IS_NPC(ch) && (dt == TYPE_CLAW || IS_VAMPAFF(ch,VAM_CLAWS)))
{
damp=number_range(1,2);
if ( damp == 1 )
{
act("You tear out $N's throat, showering the area with blood.", ch, NULL, victim, TO_CHAR);
act("$n tears out $N's throat, showering the area with blood.", ch, NULL, victim, TO_NOTVICT);
act("$n tears out your throat, showering the area with blood.", ch, NULL, victim, TO_VICT);
make_part(victim,"blood");
if (!IS_BODY(victim,CUT_THROAT))
SET_BIT(victim->loc_hp[1],CUT_THROAT);
if (!IS_BLEEDING(victim,BLEEDING_THROAT))
SET_BIT(victim->loc_hp[6],BLEEDING_THROAT);
}
if ( damp == 2 )
{
if (!IS_HEAD(victim,LOST_EYE_L) && number_percent() < 50)
{
act("You rip an eyeball from $N's face.", ch, NULL, victim, TO_CHAR);
act("$n rips an eyeball from $N's face.", ch, NULL, victim, TO_NOTVICT);
act("$n rips an eyeball from your face.", ch, NULL, victim, TO_VICT);
make_part(victim,"eyeball");
SET_BIT(victim->loc_hp[0],LOST_EYE_L);
}
else if (!IS_HEAD(victim,LOST_EYE_R))
{
act("You rip an eyeball from $N's face.", ch, NULL, victim, TO_CHAR);
act("$n rips an eyeball from $N's face.", ch, NULL, victim, TO_NOTVICT);
act("$n rips an eyeball from your face.", ch, NULL, victim, TO_VICT);
make_part(victim,"eyeball");
SET_BIT(victim->loc_hp[0],LOST_EYE_R);
}
else if (!IS_HEAD(victim,LOST_EYE_L))
{
act("You rip an eyeball from $N's face.", ch, NULL, victim, TO_CHAR);
act("$n rips an eyeball from $N's face.", ch, NULL, victim, TO_NOTVICT);
act("$n rips an eyeball from your face.", ch, NULL, victim, TO_VICT);
make_part(victim,"eyeball");
SET_BIT(victim->loc_hp[0],LOST_EYE_L);
}
else
{
act("You claw open $N's chest.", ch, NULL, victim, TO_CHAR);
act("$n claws open $N's chest.", ch, NULL, victim, TO_NOTVICT);
act("$n claws open $N's chest.", ch, NULL, victim, TO_VICT);
}
}
}
else if ( dt == TYPE_WHIP )
{
act("You entangle $N around the neck, and squeeze the life out of $M.", ch, NULL, victim, TO_CHAR);
act("$n entangles $N around the neck, and squeezes the life out of $M.", ch, NULL, victim, TO_NOTVICT);
act("$n entangles you around the neck, and squeezes the life out of you.", ch, NULL, victim, TO_VICT);
if (!IS_BODY(victim,BROKEN_NECK))
SET_BIT(victim->loc_hp[1],BROKEN_NECK);
}
else if ( dt == TYPE_SUCK || dt == TYPE_GREP )
{
act("You place your weapon on $N's head and suck out $S brains.", ch, NULL, victim, TO_CHAR);
act("$n places $s weapon on $N's head and suck out $S brains.", ch, NULL, victim, TO_NOTVICT);
act("$n places $s weapon on your head and suck out your brains.", ch, NULL, victim, TO_VICT);
}
else if ( dt == TYPE_CLAW )
{
act("You claw open $N's chest.", ch, NULL, victim, TO_CHAR);
act("$n claws open $N's chest.", ch, NULL, victim, TO_NOTVICT);
act("$n claws open $N's chest.", ch, NULL, victim, TO_VICT);
}
else if ( dt == TYPE_LIGHT )
{
act("Once the massive light beam is gone, there is nothing left of poor $N.", ch, NULL, victim, TO_CHAR);
act("$n blasts $N so hard, they turn in to dust.", ch, NULL, victim, TO_NOTVICT);
act("You just got blasted by a massive light source... Bummer.", ch, NULL, victim, TO_VICT);
}
return;
}
/*
* Disarm a creature.
* Caller must check for successful attack.
*/
void disarm( CHAR_DATA *ch, CHAR_DATA *victim )
{
OBJ_DATA *obj;
GString *tmpstring;
char buf [MAX_STRING_LENGTH];
/* I'm fed up of being disarmed every 10 seconds - KaVir */
if (!IS_NPC(victim) && !IS_IMMFLAW(victim,IMM_FLAW_DISARM))
{
if (IS_NPC(ch) && victim->level > 2 && number_percent() > 5)
return;
}
if (!IS_NPC(victim) && IS_IMMMERIT(victim, IMM_MERIT_DISARM))
return;
/*
if ( ( (obj = get_eq_char( ch, WEAR_WIELD ) == NULL) || obj->item_type != ITEM_WEAPON )
&& ( (obj = get_eq_char( ch, WEAR_HOLD ) == NULL) || obj->item_type != ITEM_WEAPON ) )
return;
*/
if ( ( (obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL) || obj->item_type != ITEM_WEAPON )
{
if ( ( (obj = get_eq_char( victim, WEAR_HOLD ) ) == NULL) || obj->item_type != ITEM_WEAPON )
return;
}
tmpstring = g_string_new("");
sprintf(buf,"{W$n disarms you!{x");
act( buf, ch, NULL, victim, TO_VICT );
sprintf(buf,"{WYou disarm $N!{x");
act( buf, ch, NULL, victim, TO_CHAR );
sprintf(buf,"{W$n disarms $N!{x");
act( buf, ch, NULL, victim, TO_NOTVICT );
obj_from_char( obj );
/* Loyal weapons come back ;) KaVir */
if (IS_SET(obj->extra_flags, ITEM_LOYAL) && ( !IS_NPC(victim) && !IS_IMMFLAW(victim,IMM_FLAW_DISARM) ))
{
act( "{c$p leaps back into your hand!{x", victim, obj, NULL, TO_CHAR );
obj_to_char( obj, victim );
do_wear( victim, obj->name->str);
act( "{c$p leaps back into $n's hand!{x", victim, obj, NULL, TO_ROOM );
}
else if ( IS_NPC(victim) )
obj_to_char( obj, victim );
else
obj_to_room( obj, victim->in_room );
return;
}
/*
* Trip a creature.
* Caller must check for successful attack.
*/
void trip( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf [MAX_STRING_LENGTH];
if (IS_AFFECTED(victim,AFF_FLYING))
return;
if (IS_NPC(ch) && victim->level > 2 && number_percent() > 5)
return;
if (!IS_NPC(victim))
{
if (IS_CLASS(victim, CLASS_VAMPIRE) && IS_VAMPAFF(victim,VAM_FLYING))
return;
}
if ( victim->wait == 0)
{
sprintf(buf,"{W$n trips you and you go down!{x");
act( buf, ch, NULL, victim, TO_VICT );
sprintf(buf,"{WYou trip $N and $E goes down!{x");
act( buf, ch, NULL, victim, TO_CHAR );
sprintf(buf,"{W$n trips $N and $E goes down!{x");
act( buf, ch, NULL, victim, TO_NOTVICT );
WAIT_STATE( ch, 2 * PULSE_VIOLENCE );
WAIT_STATE( victim, 2 * PULSE_VIOLENCE );
victim->position = POS_RESTING;
}
return;
}
int dambonus( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int stance)
{
if (dam < 1) return 0;
if (stance < 1) return dam;
if (!IS_NPC(ch) && !can_counter(victim))
{
if ( IS_STANCE(ch, STANCE_MONKEY) )
{
int mindam = (int)((double)dam * 0.25);
dam *= (ch->stance[STANCE_MONKEY]+1) / 200;
if (dam < mindam) dam = mindam;
}
else if ( IS_STANCE(ch, STANCE_BULL) && ch->stance[STANCE_BULL] > 100 )
dam += dam * (ch->stance[STANCE_BULL] / 100);
else if ( IS_STANCE(ch, STANCE_DRAGON) && ch->stance[STANCE_DRAGON] > 100 )
dam += dam * (ch->stance[STANCE_DRAGON] / 100);
else if ( IS_STANCE(ch, STANCE_TIGER) && ch->stance[STANCE_TIGER] > 100 )
dam += dam * (ch->stance[STANCE_TIGER] / 100);
else if ( ch->stance[0] > 0 && ch->stance[stance] < 100 )
dam = (int)((double)dam * 0.5);
}
if (!IS_NPC(victim) && !can_counter(ch))
{
if ( IS_STANCE(victim, STANCE_CRAB) && victim->stance[STANCE_CRAB] > 100 )
dam /= victim->stance[STANCE_CRAB]/100;
else if ( IS_STANCE(victim, STANCE_DRAGON) && victim->stance[STANCE_DRAGON] > 100 )
dam /= victim->stance[STANCE_DRAGON]/100;
else if ( IS_STANCE(victim, STANCE_SWALLOW) && victim->stance[STANCE_SWALLOW] > 100 )
dam /= victim->stance[STANCE_SWALLOW]/100;
}
return dam;
}
void crack_head( CHAR_DATA *ch, OBJ_DATA *obj, char *argument )
{
CHAR_DATA *victim;
MOB_INDEX_DATA *pMobIndex;
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char buf [MAX_INPUT_LENGTH];
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if (str_cmp(arg2,"mob") && obj->chobj != NULL && !IS_NPC(obj->chobj) &&
IS_AFFECTED(obj->chobj,AFF_POLYMORPH))
{
victim = obj->chobj;
make_part(victim,"cracked_head");
make_part(victim,"brain");
sprintf(buf,"the quivering brain of %s",victim->name->str);
victim->morph = g_string_assign(victim->morph,buf);
return;
}
else if (!str_cmp(arg2,"mob"))
{
if ( ( pMobIndex = get_mob_index( obj->value[1] ) ) == NULL ) return;
victim = create_mobile( pMobIndex );
char_to_room(victim,ch->in_room);
make_part(victim,"cracked_head");
make_part(victim,"brain");
extract_char(victim,TRUE);
return;
}
else
{
if ( ( pMobIndex = get_mob_index( 30002 ) ) == NULL ) return;
victim = create_mobile( pMobIndex );
sprintf( buf, capitalize(arg2) );
victim->short_descr = g_string_assign(victim->short_descr, buf );
char_to_room(victim,ch->in_room);
make_part(victim,"cracked_head");
make_part(victim,"brain");
extract_char(victim,TRUE);
return;
}
return;
}
/* For watchers in room to be drawn into fights.
* Original idea taken from SneezyMUD.
* Coded by Thale.
*/
void crowd_brawl(CHAR_DATA *ch)
{
CHAR_DATA *rch, *rch_next, *vch, *vch_next;
CHAR_DATA *is_fighting[5];
SHOP_DATA *pshop;
int chance;
int counter;
int count_int;
int to_fight;
int rand_msg;
for (rch = ch->in_room->people; rch != NULL; rch = rch_next)
{
rch_next = rch->next_in_room;
chance=number_range(1,300);
if ((rch->fighting == NULL)
&&((!IS_IMMORTAL(rch) && !IS_NPC(rch))
||(IS_NPC(rch)
&&!(IS_SET(rch->act,ACT_TRAIN)
|| IS_SET(rch->act,ACT_PRACTICE)
|| ((pshop = rch->pIndexData->pShop) != NULL))))
&&IS_AWAKE(rch)
&&(chance <= 2))
{
counter = 0;
for ( count_int=0; count_int<= 5; count_int++ )
{
is_fighting[count_int] = NULL;
}
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ((vch->fighting != NULL) && (counter <= 5))
{
is_fighting[counter] = vch;
++counter;
/* if it's an NPC, thrice as likely as a PC to be attacked */
/* max of 45 fighting PC/NPCs in array, can't exceed */
if ((IS_NPC(vch)) && (counter <= 5))
{
is_fighting[counter] = vch;
++counter;
}
if ((IS_NPC(vch)) && (counter <= 5))
{
is_fighting[counter] = vch;
++counter;
}
}
}
/* random number of mob in array to fight */
to_fight = number_range(1,counter);
/* (to_fight -1) because arrays start at 0 not at 1 */
to_fight -= 1;
/* checks needed for PCs only */
if (!IS_NPC(rch) && !IS_NPC(is_fighting[to_fight]))
{
/* if a Harper, won't attack another PC, and vice versa */
if (rch->level != LEVEL_AVATAR || is_fighting[to_fight]->level != LEVEL_AVATAR)
return;
/* won't attack someone of same clan */
if (rch->sect == is_fighting[to_fight]->sect)
return;
}
else if (IS_NPC(rch))
{
/* hack so adept in mud school at diploma beast won't attack
* anyone - learned the hard way, oops. :)
*/
if (rch->pIndexData->vnum == 3708)
return;
}
/* if an immortal is fighting, nothing attacks him/her */
if (IS_IMMORTAL(is_fighting[to_fight]))
return;
/* resting mobs/players have a smaller chance of being drawn in */
if ((rch->position <= POS_RESTING) && (chance > 1))
return;
/* gotta see them to attack them */
if (!can_see(rch,is_fighting[to_fight]))
return;
if ( rch == is_fighting[to_fight])
return;
/* not against group members */
if (is_same_group(rch,is_fighting[to_fight]))
return;
/* charmed mobs and pets, whether grouped or not */
if (IS_AFFECTED(rch,AFF_CHARM)
&&((rch->master == is_fighting[to_fight])
||(is_fighting[to_fight]->master == rch)
||(is_fighting[to_fight]->master == rch->master)))
return;
if (is_fighting[to_fight] != NULL)
{
rch->fighting = is_fighting[to_fight];
rch->position = POS_FIGHTING;
rand_msg = number_range(1,4);
switch (rand_msg)
{
case 1:
act("$n bumps into you, and you find yourself amist battle!",rch,NULL,NULL,TO_CHAR);
act("$N bumps into $n, and finds $mself amist battle!",rch,NULL,is_fighting[to_fight],TO_ROOM);
break;
break;
case 2:
act("$n wild swing at $N catches you standing too close.",rch,NULL,rch->fighting,TO_CHAR);
act("$n wild swing catches $N, standing too close.",rch,NULL,is_fighting[to_fight],TO_ROOM);
break;
case 3:
act("Your curiosity has gotten the best of you and you are drawn into the middle of the battle.",rch,NULL,NULL,TO_CHAR);
act("$n finds $mself involved in the brawl.",rch,NULL,NULL,TO_ROOM);
break;
case 4:
act("You find yourself caught up in the brawl!",rch,NULL,NULL,TO_CHAR);
act("$n finds $mself involved in the brawl.",rch,NULL,NULL,TO_ROOM);
break;
}
}
else
bug("Crowd_brawl - person to fight is NULL.", 0);
}
}
/*return; */
} /* end of crowd_brawl */
/*
** show_fm
*
* FILENAME: C:\lurf\code\fight.c
*
* PARAMETERS: CHAR_DATA *ch
*
* DESCRIPTION: This proc shows to people in the room the varibles of a fight.
* This will help Spiral debug fights so that he can check out the
* status and numbers of a fight with out doing a manual debug.
*
* RETURNS: Nothing
*
*/
void show_fm ( CHAR_DATA *ch, char argument[MAX_STRING_LENGTH] )
{
CHAR_DATA *victim,*victim_next;
char buf[MAX_STRING_LENGTH];
//If the incomming Show_fm() is from a mobile drop it..
//We don't need to know about mobiles YET
if (IS_NPC(ch)){
return;
}
for (victim = ch->in_room->people; victim != NULL; victim = victim_next)
{
victim_next = victim->next_in_room;
//Check if the victim has the comm bit, then if he don't run the next loop
if (IS_NPC(victim))
continue;
if (!IS_SET(victim->pcdata->comm,COMM_SHOW_FIGHT))
continue;
//You have the bit so let's show what we need to see.
sprintf(buf,"{RFight: %s{x\n\r",argument);
send_to_char(buf,victim);
}
}
void diab_finish( CHAR_DATA *victim )
{
if (IS_NPC(victim)) return;
stop_fighting( victim, TRUE );
make_corpse( victim );
extract_char( victim, FALSE );
char_from_room(victim);
char_to_room(victim,get_room_index( ROOM_VNUM_TEMPLE ));
if (victim == NULL)
{bug( "Behead: Victim no longer exists.", 0 );return;}
while ( victim->affected )
affect_remove( victim, victim->affected );
if (IS_AFFECTED(victim,AFF_POLYMORPH))
{
victim->affected_by = AFF_POLYMORPH;
}
else if (IS_AFFECTED(victim,AFF_POLYMORPH))
victim->affected_by = AFF_POLYMORPH;
else
victim->affected_by = 0;
if ( victim->hit - victim->pcdata->absorb[ABS_MOB_HP] >= 1 ||
victim->max_hit - victim->pcdata->absorb[ABS_MOB_MAX_HP] >= 1 )
{
victim->hit -= victim->pcdata->absorb[ABS_MOB_HP];
victim->max_hit -= victim->pcdata->absorb[ABS_MOB_MAX_HP];
victim->pcdata->absorb[ABS_MOB_VNUM] = 0;
victim->pcdata->absorb[ABS_MOB_HP] = 0;
victim->pcdata->absorb[ABS_MOB_MAX_HP] = 0;
}
REMOVE_BIT(victim->immune, IMM_STAKE);
REMOVE_BIT(victim->extra, TIED_UP);
REMOVE_BIT(victim->extra, GAGGED);
REMOVE_BIT(victim->extra, BLINDFOLDED);
REMOVE_BIT(victim->extra, EXTRA_PREGNANT);
REMOVE_BIT(victim->extra, EXTRA_LABOUR);
victim->itemaffect = 0;
victim->loc_hp[0] = 0;
victim->loc_hp[1] = 0;
victim->loc_hp[2] = 0;
victim->loc_hp[3] = 0;
victim->loc_hp[4] = 0;
victim->loc_hp[5] = 0;
victim->loc_hp[6] = 0;
victim->affected_by = 0;
victim->armor = 100;
victim->position = POS_STANDING;
victim->hit = 1;
victim->mana = UMAX( 1, victim->mana );
victim->move = UMAX( 1, victim->move );
victim->hitroll = 0;
victim->damroll = 0;
victim->saving_throw = 0;
victim->carry_weight = 0;
victim->carry_number = 0;
if (IS_SWWF(victim))
shape_shift(victim, SHAPE_HOMID);
do_call(victim,"all");
do_save(victim,"");
return;
}