Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

fight.c File Reference

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "interp.h"
#include "tables.h"
#include "lookup.h"

Include dependency graph for fight.c:

Go to the source code of this file.

Functions

void raw_kill args ((CHAR_DATA *victim))
void mob_hit args ((CHAR_DATA *ch, CHAR_DATA *victim, int dt))
void one_hit args ((CHAR_DATA *ch, CHAR_DATA *victim, int dt, bool secondary))
int xp_compute args ((CHAR_DATA *gch, CHAR_DATA *victim, int total_levels))
void death_cry args ((CHAR_DATA *ch))
void dam_message args ((CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, bool immune))
void check_assist args ((CHAR_DATA *ch, CHAR_DATA *victim))
void check_assist (CHAR_DATA *ch, CHAR_DATA *victim)
bool check_dodge (CHAR_DATA *ch, CHAR_DATA *victim)
void check_killer (CHAR_DATA *ch, CHAR_DATA *victim)
bool check_parry (CHAR_DATA *ch, CHAR_DATA *victim)
bool check_shield_block (CHAR_DATA *ch, CHAR_DATA *victim)
void dam_message (CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, bool immune)
bool damage (CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, int dam_type, bool show)
void death_cry (CHAR_DATA *ch)
void disarm (CHAR_DATA *ch, CHAR_DATA *victim)
void do_backstab (CHAR_DATA *ch, char *argument)
void do_bash (CHAR_DATA *ch, char *argument)
void do_berserk (CHAR_DATA *ch, char *argument)
void do_dirt (CHAR_DATA *ch, char *argument)
void do_disarm (CHAR_DATA *ch, char *argument)
void do_flee (CHAR_DATA *ch, char *argument)
void do_kick (CHAR_DATA *ch, char *argument)
void do_kill (CHAR_DATA *ch, char *argument)
void do_murde (CHAR_DATA *ch, char *argument)
void do_murder (CHAR_DATA *ch, char *argument)
void do_rescue (CHAR_DATA *ch, char *argument)
void do_sla (CHAR_DATA *ch, char *argument)
void do_slay (CHAR_DATA *ch, char *argument)
void do_surrender (CHAR_DATA *ch, char *argument)
void do_trip (CHAR_DATA *ch, char *argument)
void group_gain (CHAR_DATA *ch, CHAR_DATA *victim)
bool is_safe (CHAR_DATA *ch, CHAR_DATA *victim)
bool is_safe_spell (CHAR_DATA *ch, CHAR_DATA *victim, bool area)
void make_corpse (CHAR_DATA *ch)
void mob_hit (CHAR_DATA *ch, CHAR_DATA *victim, int dt)
void multi_hit (CHAR_DATA *ch, CHAR_DATA *victim, int dt)
void one_hit (CHAR_DATA *ch, CHAR_DATA *victim, int dt, bool secondary)
void raw_kill (CHAR_DATA *victim)
void set_fighting (CHAR_DATA *ch, CHAR_DATA *victim)
void stop_fighting (CHAR_DATA *ch, bool fBoth)
void update_pos (CHAR_DATA *victim)
void violence_update (void)
int xp_compute (CHAR_DATA *gch, CHAR_DATA *victim, int total_levels)


Function Documentation

void raw_kill args (CHAR_DATA *victim)   ) 
 

void mob_hit args (CHAR_DATA *ch, CHAR_DATA *victim, int dt)   ) 
 

void one_hit args (CHAR_DATA *ch, CHAR_DATA *victim, int dt, bool secondary)   ) 
 

int xp_compute args (CHAR_DATA *gch, CHAR_DATA *victim, int total_levels)   ) 
 

void death_cry args (CHAR_DATA *ch)   ) 
 

void dam_message args (CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, bool immune)   ) 
 

void check_assist args (CHAR_DATA *ch, CHAR_DATA *victim)   ) 
 

void check_assist CHAR_DATA ch,
CHAR_DATA victim
 

Definition at line 113 of file fight.c.

References AFF_CHARM, ASSIST_ALIGN, ASSIST_ALL, ASSIST_PLAYERS, ASSIST_RACE, ASSIST_VNUM, can_see(), do_emote(), do_function(), char_data::in_room, IS_AFFECTED, IS_AWAKE, IS_EVIL, IS_GOOD, IS_NEUTRAL, IS_NPC, is_safe(), is_same_group(), IS_SET, multi_hit(), char_data::next, char_data::next_in_room, number_bits(), number_range(), room_index_data::people, PLR_AUTOASSIST, and TYPE_UNDEFINED.

Referenced by violence_update().

00114 {
00115     CHAR_DATA *rch, *rch_next;
00116 
00117     for (rch = ch->in_room->people; rch != NULL; rch = rch_next)
00118     {
00119         rch_next = rch->next_in_room;
00120 
00121         if (IS_AWAKE (rch) && rch->fighting == NULL)
00122         {
00123 
00124             /* quick check for ASSIST_PLAYER */
00125             if (!IS_NPC (ch) && IS_NPC (rch)
00126                 && IS_SET (rch->off_flags, ASSIST_PLAYERS)
00127                 && rch->level + 6 > victim->level)
00128             {
00129                 do_function (rch, &do_emote, "screams and attacks!");
00130                 multi_hit (rch, victim, TYPE_UNDEFINED);
00131                 continue;
00132             }
00133 
00134             /* PCs next */
00135             if (!IS_NPC (ch) || IS_AFFECTED (ch, AFF_CHARM))
00136             {
00137                 if (((!IS_NPC (rch) && IS_SET (rch->act, PLR_AUTOASSIST))
00138                      || IS_AFFECTED (rch, AFF_CHARM))
00139                     && is_same_group (ch, rch) && !is_safe (rch, victim))
00140                     multi_hit (rch, victim, TYPE_UNDEFINED);
00141 
00142                 continue;
00143             }
00144 
00145             /* now check the NPC cases */
00146 
00147             if (IS_NPC (ch) && !IS_AFFECTED (ch, AFF_CHARM))
00148             {
00149                 if ((IS_NPC (rch) && IS_SET (rch->off_flags, ASSIST_ALL))
00150                     || (IS_NPC (rch) && rch->group && rch->group == ch->group)
00151                     || (IS_NPC (rch) && rch->race == ch->race
00152                         && IS_SET (rch->off_flags, ASSIST_RACE))
00153                     || (IS_NPC (rch) && IS_SET (rch->off_flags, ASSIST_ALIGN)
00154                         && ((IS_GOOD (rch) && IS_GOOD (ch))
00155                             || (IS_EVIL (rch) && IS_EVIL (ch))
00156                             || (IS_NEUTRAL (rch) && IS_NEUTRAL (ch))))
00157                     || (rch->pIndexData == ch->pIndexData
00158                         && IS_SET (rch->off_flags, ASSIST_VNUM)))
00159                 {
00160                     CHAR_DATA *vch;
00161                     CHAR_DATA *target;
00162                     int number;
00163 
00164                     if (number_bits (1) == 0)
00165                         continue;
00166 
00167                     target = NULL;
00168                     number = 0;
00169                     for (vch = ch->in_room->people; vch; vch = vch->next)
00170                     {
00171                         if (can_see (rch, vch)
00172                             && is_same_group (vch, victim)
00173                             && number_range (0, number) == 0)
00174                         {
00175                             target = vch;
00176                             number++;
00177                         }
00178                     }
00179 
00180                     if (target != NULL)
00181                     {
00182                         do_function (rch, &do_emote, "screams and attacks!");
00183                         multi_hit (rch, target, TYPE_UNDEFINED);
00184                     }
00185                 }
00186             }
00187         }
00188     }
00189 }

Here is the call graph for this function:

bool check_dodge CHAR_DATA ch,
CHAR_DATA victim
 

Definition at line 1488 of file fight.c.

References act, can_see(), check_improve(), FALSE, get_skill(), gsn_dodge, IS_AWAKE, number_percent(), TO_CHAR, TO_VICT, and TRUE.

Referenced by damage().

01489 {
01490     int chance;
01491 
01492     if (!IS_AWAKE (victim))
01493         return FALSE;
01494 
01495     chance = get_skill (victim, gsn_dodge) / 2;
01496 
01497     if (!can_see (victim, ch))
01498         chance /= 2;
01499 
01500     if (number_percent () >= chance + victim->level - ch->level)
01501         return FALSE;
01502 
01503     act ("You dodge $n's attack.", ch, NULL, victim, TO_VICT);
01504     act ("$N dodges your attack.", ch, NULL, victim, TO_CHAR);
01505     check_improve (victim, gsn_dodge, TRUE, 6);
01506     return TRUE;
01507 }

Here is the call graph for this function:

void check_killer CHAR_DATA ch,
CHAR_DATA victim
 

Definition at line 1360 of file fight.c.

References AFF_CHARM, affect_strip(), bug(), gsn_charm_person, IS_AFFECTED, is_clan(), IS_NPC, IS_SET, LEVEL_IMMORTAL, MAX_STRING_LENGTH, PLR_KILLER, PLR_THIEF, REMOVE_BIT, save_char_obj(), send_to_char(), SET_BIT, stop_follower(), WIZ_FLAGS, and wiznet().

Referenced by damage(), do_backstab(), do_bash(), do_cast(), do_dirt(), do_disarm(), do_kick(), do_kill(), do_murder(), do_rescue(), do_side_kick(), do_trip(), and obj_cast_spell().

01361 {
01362     char buf[MAX_STRING_LENGTH];
01363     /*
01364      * Follow charm thread to responsible character.
01365      * Attacking someone's charmed char is hostile!
01366      */
01367     while (IS_AFFECTED (victim, AFF_CHARM) && victim->master != NULL)
01368         victim = victim->master;
01369 
01370     /*
01371      * NPC's are fair game.
01372      * So are killers and thieves.
01373      */
01374     if (IS_NPC (victim)
01375         || IS_SET (victim->act, PLR_KILLER)
01376         || IS_SET (victim->act, PLR_THIEF))
01377         return;
01378 
01379     /*
01380      * Charm-o-rama.
01381      */
01382     if (IS_SET (ch->affected_by, AFF_CHARM))
01383     {
01384         if (ch->master == NULL)
01385         {
01386             char buf[MAX_STRING_LENGTH];
01387 
01388             sprintf (buf, "Check_killer: %s bad AFF_CHARM",
01389                      IS_NPC (ch) ? ch->short_descr : ch->name);
01390             bug (buf, 0);
01391             affect_strip (ch, gsn_charm_person);
01392             REMOVE_BIT (ch->affected_by, AFF_CHARM);
01393             return;
01394         }
01395 /*
01396     send_to_char( "*** You are now a KILLER!! ***\n\r", ch->master );
01397       SET_BIT(ch->master->act, PLR_KILLER);
01398 */
01399 
01400         stop_follower (ch);
01401         return;
01402     }
01403 
01404     /*
01405      * NPC's are cool of course (as long as not charmed).
01406      * Hitting yourself is cool too (bleeding).
01407      * So is being immortal (Alander's idea).
01408      * And current killers stay as they are.
01409      */
01410     if (IS_NPC (ch)
01411         || ch == victim || ch->level >= LEVEL_IMMORTAL || !is_clan (ch)
01412         || IS_SET (ch->act, PLR_KILLER) || ch->fighting == victim)
01413         return;
01414 
01415     send_to_char ("*** You are now a KILLER!! ***\n\r", ch);
01416     SET_BIT (ch->act, PLR_KILLER);
01417     sprintf (buf, "$N is attempting to murder %s", victim->name);
01418     wiznet (buf, ch, NULL, WIZ_FLAGS, 0, 0);
01419     save_char_obj (ch);
01420     return;
01421 }

Here is the call graph for this function:

bool check_parry CHAR_DATA ch,
CHAR_DATA victim
 

Definition at line 1428 of file fight.c.

References act, can_see(), check_improve(), FALSE, get_eq_char(), get_skill(), gsn_parry, IS_AWAKE, IS_NPC, number_percent(), TO_CHAR, TO_VICT, TRUE, and WEAR_WIELD.

Referenced by damage().

01429 {
01430     int chance;
01431 
01432     if (!IS_AWAKE (victim))
01433         return FALSE;
01434 
01435     chance = get_skill (victim, gsn_parry) / 2;
01436 
01437     if (get_eq_char (victim, WEAR_WIELD) == NULL)
01438     {
01439         if (IS_NPC (victim))
01440             chance /= 2;
01441         else
01442             return FALSE;
01443     }
01444 
01445     if (!can_see (ch, victim))
01446         chance /= 2;
01447 
01448     if (number_percent () >= chance + victim->level - ch->level)
01449         return FALSE;
01450 
01451     act ("You parry $n's attack.", ch, NULL, victim, TO_VICT);
01452     act ("$N parries your attack.", ch, NULL, victim, TO_CHAR);
01453     check_improve (victim, gsn_parry, TRUE, 6);
01454     return TRUE;
01455 }

Here is the call graph for this function:

bool check_shield_block CHAR_DATA ch,
CHAR_DATA victim
 

Definition at line 1460 of file fight.c.

References act, check_improve(), FALSE, get_eq_char(), get_skill(), gsn_shield_block, IS_AWAKE, number_percent(), TO_CHAR, TO_VICT, TRUE, and WEAR_SHIELD.

Referenced by damage().

01461 {
01462     int chance;
01463 
01464     if (!IS_AWAKE (victim))
01465         return FALSE;
01466 
01467 
01468     chance = get_skill (victim, gsn_shield_block) / 5 + 3;
01469 
01470 
01471     if (get_eq_char (victim, WEAR_SHIELD) == NULL)
01472         return FALSE;
01473 
01474     if (number_percent () >= chance + victim->level - ch->level)
01475         return FALSE;
01476 
01477     act ("You block $n's attack with your shield.", ch, NULL, victim,
01478          TO_VICT);
01479     act ("$N blocks your attack with a shield.", ch, NULL, victim, TO_CHAR);
01480     check_improve (victim, gsn_shield_block, TRUE, 6);
01481     return TRUE;
01482 }

Here is the call graph for this function:

void dam_message CHAR_DATA ch,
CHAR_DATA victim,
int  dam,
int  dt,
bool  immune
 

Definition at line 2189 of file fight.c.

References act, attack_table, bug(), MAX_DAMAGE_MESSAGE, MAX_SKILL, attack_type::name, attack_type::noun, skill_type::noun_damage, skill_table, TO_CHAR, TO_NOTVICT, TO_ROOM, TO_VICT, and TYPE_HIT.

Referenced by damage().

02191 {
02192     char buf1[256], buf2[256], buf3[256];
02193     const char *vs;
02194     const char *vp;
02195     const char *attack;
02196     char punct;
02197 //    int dam_percent = ((200 * dam) / victim->max_hit);
02198     int dam_percent = dam * 3 / 4;
02199     dam = dam_percent;
02200 //sprintf(buf1, "DAMAGE GIVEN: %d DAMAGE AFTER DIVISION %d\n\r",dam, ((100 * dam)/victim->max_hit));
02201 //send_to_char(buf1,ch);
02202 //sprintf(buf1, "DAMAGE FROM OTHER: %d DAMAGE AFTER DIVISION %d\n\r", dam, ((100 * dam)/victim->max_hit));
02203 //send_to_char(buf1,ch);
02204     if (ch == NULL || victim == NULL)
02205         return;
02206 
02207 
02208     if (dam == 0)
02209     {
02210         vs = "{ymiss{x";
02211         vp = "{ymisses{x";
02212     }
02213     else if (dam_percent <= 5)
02214     {
02215         vs = "{gscratch{x";
02216         vp = "{gscratches{x";
02217     }
02218     else if (dam_percent <= 10)
02219     {
02220         vs = "{ggraze{x";
02221         vp = "{ggrazes{x";
02222     }
02223     else if (dam_percent <= 15)
02224     {
02225         vs = "{ghit{x";
02226         vp = "{ghits{x";
02227     }
02228     else if (dam_percent <= 20)
02229     {
02230         vs = "{ginjure{x";
02231         vp = "{ginjures{x";
02232     }
02233     else if (dam_percent <= 25)
02234     {
02235         vs = "{gwound{x";
02236         vp = "{gwounds{x";
02237     }
02238     else if (dam_percent <= 30)
02239     {
02240         vs = "{gmaul{x";
02241         vp = "{gmauls{x";
02242     }
02243     else if (dam_percent <= 35)
02244     {
02245         vs = "{gdecimate{x";
02246         vp = "{gdecimates{x";
02247     }
02248     else if (dam_percent <= 40)
02249     {
02250         vs = "{gdevastate{x";
02251         vp = "{gdevastates{x";
02252     }
02253     else if (dam_percent <= 45)
02254     {
02255         vs = "{gmaim{x";
02256         vp = "{gmaims{x";
02257     }
02258     else if (dam_percent <= 50)
02259     {
02260         vs = "{YMUTILATE{x";
02261         vp = "{YMUTILATES{x";
02262     }
02263     else if (dam_percent <= 55)
02264     {
02265         vs = "{YDISEMBOWEL{x";
02266         vp = "{YDISEMBOWELS{x";
02267     }
02268     else if (dam_percent <= 60)
02269     {
02270         vs = "{YDISMEMBER{x";
02271         vp = "{YDISMEMBERS{x";
02272     }
02273     else if (dam_percent <= 65)
02274     {
02275         vs = "{YMASSACRE{x";
02276         vp = "{YMASSACRES{x";
02277     }
02278     else if (dam_percent <= 70)
02279     {
02280         vs = "{YMANGLE{x";
02281         vp = "{YMANGLES{x";
02282     }
02283     else if (dam_percent <= 75)
02284     {
02285         vs = "{x*** {RDEMOLISH{x ***";
02286         vp = "{x***{RDEMOLISHES{x ***";
02287     }
02288     else if (dam_percent <= 80)
02289     {
02290         vs = "{x*** {RDEVASTATE{x ***";
02291         vp = "{x*** {RDEVASTATES{x ***";
02292     }
02293     else if (dam_percent <= 85)
02294     {
02295         vs = "{R=== {ROBLITERATE {R==={x";
02296         vp = "{R=== {ROBLITERATES {R==={x";
02297     }
02298     else if (dam_percent <= 90)
02299     {
02300         vs = "{R>>> {RANNIHILATE{R <<<{x";
02301         vp = "{R>>> {RANNIHILATES {R<<<{x";
02302     }
02303     else if (dam_percent <= 95)
02304     {
02305         vs = "{R<<< ERADICATE >>>{x";
02306         vp = "{R<<< ERADICATES >>>{x";
02307     }
02308     else
02309     {
02310         vs = "{xdo {RU{WN{RS{WP{RE{WA{RK{WA{RB{WL{RE {xthings to";
02311         vp = "{xdoes {RU{WN{RS{WP{RE{WA{RK{WA{RB{WL{RE {xthings to";
02312     }
02313 
02314     punct = (dam_percent <= 45) ? '.' : '!';
02315 
02316     if (dt == TYPE_HIT)
02317     {
02318         if (ch == victim)
02319         {
02320             sprintf (buf1, "{3$n %s $melf%c{x", vp, punct);
02321             sprintf (buf2, "{2You %s yourself%c{x", vs, punct);
02322         }
02323         else
02324         {
02325             sprintf (buf1, "{3$n %s $N%c{x", vp, punct);
02326             sprintf (buf2, "{2You %s $N%c{x", vs, punct);
02327             sprintf (buf3, "{4$n %s you%c{x", vp, punct);
02328         }
02329     }
02330     else
02331     {
02332         if (dt >= 0 && dt < MAX_SKILL)
02333             attack = skill_table[dt].noun_damage;
02334         else if (dt >= TYPE_HIT && dt < TYPE_HIT + MAX_DAMAGE_MESSAGE)
02335             attack = attack_table[dt - TYPE_HIT].noun;
02336         else
02337         {
02338             bug ("Dam_message: bad dt %d.", dt);
02339             dt = TYPE_HIT;
02340             attack = attack_table[0].name;
02341         }
02342 
02343         if (immune)
02344         {
02345             if (ch == victim)
02346             {
02347                 sprintf (buf1, "{3$n is unaffected by $s own %s.{x", attack);
02348                 sprintf (buf2, "{2Luckily, you are immune to that.{x");
02349             }
02350             else
02351             {
02352                 sprintf (buf1, "{3$N is unaffected by $n's %s!{x", attack);
02353                 sprintf (buf2, "{2$N is unaffected by your %s!{x", attack);
02354                 sprintf (buf3, "{4$n's %s is powerless against you.{x",
02355                          attack);
02356             }
02357         }
02358         else
02359         {
02360             if (ch == victim)
02361             {
02362                 sprintf (buf1, "{3$n's %s %s $m%c{x", attack, vp, punct);
02363                 sprintf (buf2, "{2Your %s %s you%c{x", attack, vp, punct);
02364             }
02365             else
02366             {
02367                 sprintf (buf1, "{3$n's %s %s $N%c{x", attack, vp, punct);
02368                 sprintf (buf2, "{2Your %s %s $N%c{x", attack, vp, punct);
02369                 sprintf (buf3, "{4$n's %s %s you%c{x", attack, vp, punct);
02370             }
02371         }
02372     }
02373 
02374     if (ch == victim)
02375     {
02376         act (buf1, ch, NULL, NULL, TO_ROOM);
02377         act (buf2, ch, NULL, NULL, TO_CHAR);
02378     }
02379     else
02380     {
02381         act (buf1, ch, NULL, victim, TO_NOTVICT);
02382         act (buf2, ch, NULL, victim, TO_CHAR);
02383         act (buf3, ch, NULL, victim, TO_VICT);
02384     }
02385     return;
02386 }

Here is the call graph for this function:

bool damage CHAR_DATA ch,
CHAR_DATA victim,
int  dam,
int  dt,
int  dam_type,
bool  show
 

Definition at line 742 of file fight.c.

References act, ACT_WIMPY, AFF_CHARM, AFF_INVISIBLE, AFF_PROTECT_EVIL, AFF_PROTECT_GOOD, AFF_SANCTUARY, affect_strip(), bug(), can_see_obj(), descriptor_data::character, check_dodge(), check_immune(), check_killer(), check_parry(), check_shield_block(), CON_PLAYING, COND_DRUNK, descriptor_data::connected, obj_data::contains, dam_message(), descriptor_list, do_flee(), do_function(), do_get(), do_recall(), do_sacrifice(), exp_per_level(), extract_obj(), FALSE, gain_exp(), get_eq_char(), get_obj_list(), global_peace, group_gain(), gsn_invis, gsn_mass_invis, HAS_TRIGGER, IS_AFFECTED, IS_AWAKE, IS_EVIL, IS_GOOD, IS_IMMORTAL, IS_IMMUNE, IS_NPC, IS_RESISTANT, is_safe(), is_same_clan(), IS_SET, IS_VULNERABLE, ITEM_CORPSE_NPC, obj_data::item_type, LEVEL_IMMORTAL, log_buf, log_string(), MAX_STRING_LENGTH, mp_percent_trigger(), descriptor_data::next, number_bits(), number_range(), PLR_AUTOGOLD, PLR_AUTOLOOT, PLR_AUTOSAC, PLR_KILLER, PLR_THIEF, POS_DEAD, POS_FIGHTING, POS_INCAP, POS_MORTAL, POS_STANDING, POS_STUNNED, char_data::position, PULSE_VIOLENCE, raw_kill(), REMOVE_BIT, SECT_ARENA, room_index_data::sector_type, send_to_all(), send_to_char(), set_fighting(), stop_fighting(), stop_follower(), str_cmp(), tail_chain(), TO_ROOM, TRIG_DEATH, TRIG_KILL, TRUE, TYPE_HIT, update_pos(), WEAR_WIELD, WIZ_DEATHS, WIZ_MOBDEATHS, and wiznet().

Referenced by char_update(), do_backstab(), do_bash(), do_dirt(), do_kick(), do_mpdamage(), do_side_kick(), do_trip(), one_hit(), spell_acid_blast(), spell_acid_breath(), spell_burning_hands(), spell_call_lightning(), spell_cause_critical(), spell_cause_light(), spell_cause_serious(), spell_chain_lightning(), spell_chill_touch(), spell_colour_spray(), spell_demonfire(), spell_dispel_evil(), spell_dispel_good(), spell_earthquake(), spell_energy_drain(), spell_fire_breath(), spell_fireball(), spell_flamestrike(), spell_frost_breath(), spell_gas_breath(), spell_general_purpose(), spell_harm(), spell_heat_metal(), spell_high_explosive(), spell_holy_word(), spell_lightning_bolt(), spell_lightning_breath(), spell_magic_missile(), spell_ray_of_truth(), spell_shocking_grasp(), and spell_tribul_kill().

00744 {
00745     OBJ_DATA *corpse;
00746     bool immune;
00747 //    DESCRIPTOR_DATA *d_next;
00748      DESCRIPTOR_DATA *d;
00749      CHAR_DATA *wch;
00750      char buf3[MAX_STRING_LENGTH];
00751      ROOM_INDEX_DATA *in_room;
00752     in_room = victim->in_room;
00753     extern bool global_peace;
00754     if (global_peace)
00755     {
00756         send_to_char("The Gods of peace have spoken. There will be no fighting.\n\r",ch);
00757         return FALSE;
00758     }
00759 
00760     if (victim->position == POS_DEAD)
00761     {
00762         stop_fighting(victim, TRUE);
00763         return FALSE;
00764     }
00765     if (ch->position == POS_DEAD)
00766     {
00767         stop_fighting(ch, TRUE);
00768         return FALSE;
00769     }
00770 /*
00771     if (!IS_NPC(victim) && !IS_NPC(ch) && ch->clan == 0 && victim != ch)
00772     {
00773         send_to_char("Join a clan if you wish to attack players.\n\r",ch);
00774         return FALSE;
00775     }
00776     if (!IS_NPC(victim) && !IS_NPC(ch) && victim->clan == 0 &&  victim != ch)
00777     {
00778         send_to_char("They are not in a clan.\n\r",ch);
00779         return FALSE;
00780     }
00781 */
00782     /*
00783      * Stop up any residual loopholes.
00784      */
00785    // if (dam > 1200 && dt >= TYPE_HIT)
00786 if (dam > 2000)    
00787 {
00788         bug ("Damage: %d: more than 2000 points!", dam);
00789         dam = 1999;
00790         if (!IS_IMMORTAL (ch))
00791         {
00792             OBJ_DATA *obj;
00793             obj = get_eq_char (ch, WEAR_WIELD);
00794             send_to_char ("You really shouldn't cheat.\n\r", ch);
00795             if (obj != NULL)
00796                 extract_obj (obj);
00797         }
00798 
00799     }
00800 
00801 
00802     /* damage reduction */
00803    if (dam > 35)
00804         dam = (dam - 35) / 2 + 35;
00805     if (dam > 80)
00806         dam = (dam - 80) / 2 + 80;
00807 
00808 
00809 
00810 
00811     if (victim != ch)
00812     {
00813         /*
00814          * Certain attacks are forbidden.
00815          * Most other attacks are returned.
00816          */
00817         if (is_safe (ch, victim))
00818             return FALSE;
00819         check_killer (ch, victim);
00820 
00821         if (victim->position > POS_STUNNED)
00822         {
00823             if (victim->fighting == NULL)
00824             {
00825                 set_fighting (victim, ch);
00826                 if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_KILL))
00827                     mp_percent_trigger (victim, ch, NULL, NULL, TRIG_KILL);
00828             }
00829             if (victim->timer <= 4)
00830                 victim->position = POS_FIGHTING;
00831         }
00832 
00833         if (victim->position > POS_STUNNED)
00834         {
00835             if (ch->fighting == NULL)
00836                 set_fighting (ch, victim);
00837         }
00838 
00839         /*
00840          * More charm stuff.
00841          */
00842         if (victim->master == ch)
00843             stop_follower (victim);
00844     }
00845 
00846     /*
00847      * Inviso attacks ... not.
00848      */
00849     if (IS_AFFECTED (ch, AFF_INVISIBLE))
00850     {
00851         affect_strip (ch, gsn_invis);
00852         affect_strip (ch, gsn_mass_invis);
00853         REMOVE_BIT (ch->affected_by, AFF_INVISIBLE);
00854         act ("$n fades into existence.", ch, NULL, NULL, TO_ROOM);
00855     }
00856 
00857     /*
00858      * Damage modifiers.
00859      */
00860 
00861     if (dam > 1 && !IS_NPC (victim)
00862         && victim->pcdata->condition[COND_DRUNK] > 10)
00863         dam = 9 * dam / 10;
00864 
00865     if (dam > 1 && IS_AFFECTED (victim, AFF_SANCTUARY))
00866         dam /= 2;
00867 
00868     if (dam > 1 && ((IS_AFFECTED (victim, AFF_PROTECT_EVIL) && IS_EVIL (ch))
00869                     || (IS_AFFECTED (victim, AFF_PROTECT_GOOD)
00870                         && IS_GOOD (ch))))
00871         dam -= dam / 4;
00872 
00873     immune = FALSE;
00874 
00875 
00876     /*
00877      * Check for parry, and dodge.
00878      */
00879     if (dt >= TYPE_HIT && ch != victim)
00880     {
00881         if (check_parry (ch, victim))
00882             return FALSE;
00883         if (check_dodge (ch, victim))
00884             return FALSE;
00885         if (check_shield_block (ch, victim))
00886             return FALSE;
00887 
00888     }
00889 
00890     switch (check_immune (victim, dam_type))
00891     {
00892         case (IS_IMMUNE):
00893             immune = TRUE;
00894             dam = 0;
00895             break;
00896         case (IS_RESISTANT):
00897             dam -= dam / 3;
00898             break;
00899         case (IS_VULNERABLE):
00900             dam += dam / 2;
00901             break;
00902     }
00903 
00904     if (show)
00905         dam_message (ch, victim, dam, dt, immune);
00906 
00907     if (dam == 0)
00908         return FALSE;
00909 
00910     /*
00911      * Hurt the victim.
00912      * Inform the victim of his new state.
00913      */
00914     victim->hit -= dam;
00915     if (!IS_NPC (victim)
00916         && victim->level >= LEVEL_IMMORTAL && victim->hit < 1)
00917         victim->hit = 1;
00918     update_pos (victim);
00919 
00920     switch (victim->position)
00921     {
00922         case POS_MORTAL:
00923             act ("$n is mortally wounded, and will die soon, if not aided.",
00924                  victim, NULL, NULL, TO_ROOM);
00925             send_to_char
00926                 ("You are mortally wounded, and will die soon, if not aided.\n\r",
00927                  victim);
00928             break;
00929 
00930         case POS_INCAP:
00931             act ("$n is incapacitated and will slowly die, if not aided.",
00932                  victim, NULL, NULL, TO_ROOM);
00933             send_to_char
00934                 ("You are incapacitated and will slowly die, if not aided.\n\r",
00935                  victim);
00936             break;
00937 
00938         case POS_STUNNED:
00939             act ("$n is stunned, but will probably recover.",
00940                  victim, NULL, NULL, TO_ROOM);
00941             send_to_char ("You are stunned, but will probably recover.\n\r",
00942                           victim);
00943             break;
00944 
00945         case POS_DEAD:
00946        // char buf[MAX_STRING_LENGTH]; 
00947     if (IS_NPC(ch) &&  !IS_NPC(victim) &&  (!str_cmp(ch->short_descr, "A large Black bear") 
00948                ||   !str_cmp(ch->short_descr, "A large {DBlack{x bear")))
00949     {
00950         sprintf(buf3, "%s was {RKILLED{x by the arena Bear!\n\r", victim->name);
00951         send_to_all("",buf3);
00952     }
00953     
00954         
00955         
00956         if (!IS_NPC(ch) && !IS_NPC(victim))
00957            {
00958            for (d = descriptor_list; d != NULL; d = d->next)
00959             {
00960               if (d->connected == CON_PLAYING)
00961                 {
00962             wch=d->character;
00963                 sprintf(buf3, "%s was {RKILLED{x by %s %s\n\r", victim->name,ch->name, 
00964                     in_room->sector_type == SECT_ARENA ? "{D({rArena{D){x" : "");
00965                 send_to_char(buf3,wch); 
00966                 stop_fighting(victim,TRUE);
00967         
00968             }
00969             }
00970            } //act ("{R$n is DEAD!!{x", victim, 0, 0, TO_ROOM);
00971             //send_to_char ("{RYou have been KILLED!!{x\n\r\n\r", victim);
00972         
00973         else
00974         {
00975             act("{R$n is DEAD!!{x", victim, 0, 0, TO_ROOM);
00976             send_to_char("{RYou have been KILLED!!{x\n\r\n\r",victim);
00977         }
00978         
00979         break;
00980 
00981         default:
00982             if (dam > victim->max_hit / 4)
00983                 send_to_char ("{RThat really did HURT!{x\n\r", victim);
00984             if (victim->hit < victim->max_hit / 4)
00985                 send_to_char ("{RYou sure are BLEEDING!{x\n\r", victim);
00986             break;
00987     }
00988 
00989     /*
00990      * Sleep spells and extremely wounded folks.
00991      */
00992     if (!IS_AWAKE (victim))
00993         stop_fighting (victim, FALSE);
00994 
00995     /*
00996      * Payoff for killing things.
00997      */
00998     if (victim->position == POS_DEAD)
00999     {
01000         //ROOM_INDEX_DATA *room_type;
01001     //room_type = victim->in_room;
01002        /* if (IS_SET(victim->in_room->room_flags, ROOM_NO_DEATH))
01003     {
01004         pc_death_nodeath(victim);
01005         return;
01006     }*/
01007     group_gain (ch, victim);
01008 
01009         if (!IS_NPC (victim))
01010         {
01011             sprintf (log_buf, "%s killed by %s at %d",
01012                      victim->name,
01013                      (IS_NPC (ch) ? ch->short_descr : ch->name),
01014                      ch->in_room->vnum);
01015             log_string (log_buf);
01016 
01017             /*
01018              * Dying penalty:
01019              * 2/3 way back to previous level.
01020              */
01021             if (victim->exp > exp_per_level (victim, victim->pcdata->points)
01022                 * victim->level)
01023                 gain_exp (victim,
01024                           (2 *
01025                            (exp_per_level (victim, victim->pcdata->points) *
01026                             victim->level - victim->exp) / 3) + 50);
01027         }
01028 
01029         sprintf (log_buf, "%s got toasted by %s at %s [room %d]",
01030                  (IS_NPC (victim) ? victim->short_descr : victim->name),
01031                  (IS_NPC (ch) ? ch->short_descr : ch->name),
01032                  ch->in_room->name, ch->in_room->vnum);
01033 
01034         if (IS_NPC (victim))
01035             wiznet (log_buf, NULL, NULL, WIZ_MOBDEATHS, 0, 0);
01036         else
01037             wiznet (log_buf, NULL, NULL, WIZ_DEATHS, 0, 0);
01038 
01039         /*
01040          * Death trigger
01041          */
01042         if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_DEATH))
01043         {
01044             victim->position = POS_STANDING;
01045             mp_percent_trigger (victim, ch, NULL, NULL, TRIG_DEATH);
01046         }
01047 
01048         raw_kill (victim);
01049         /* dump the flags */
01050         if (ch != victim && !IS_NPC (ch) && !is_same_clan (ch, victim))
01051         {
01052             if (IS_SET (victim->act, PLR_KILLER))
01053                 REMOVE_BIT (victim->act, PLR_KILLER);
01054             else
01055                 REMOVE_BIT (victim->act, PLR_THIEF);
01056         }
01057 
01058         /* RT new auto commands */
01059 
01060         if (!IS_NPC (ch)
01061             && (corpse =
01062                 get_obj_list (ch, "corpse", ch->in_room->contents)) != NULL
01063             && corpse->item_type == ITEM_CORPSE_NPC
01064             && can_see_obj (ch, corpse))
01065         {
01066             OBJ_DATA *coins;
01067 
01068             corpse = get_obj_list (ch, "corpse", ch->in_room->contents);
01069 
01070             if (IS_SET (ch->act, PLR_AUTOLOOT) && corpse && corpse->contains)
01071             {                    /* exists and not empty */
01072                 do_function (ch, &do_get, "all corpse");
01073             }
01074 
01075             if (IS_SET (ch->act, PLR_AUTOGOLD) && corpse && corpse->contains &&    /* exists and not empty */
01076                 !IS_SET (ch->act, PLR_AUTOLOOT))
01077             {
01078                 if ((coins = get_obj_list (ch, "gcash", corpse->contains))
01079                     != NULL)
01080                 {
01081                     do_function (ch, &do_get, "all.gcash corpse");
01082                 }
01083             }
01084 
01085             if (IS_SET (ch->act, PLR_AUTOSAC))
01086             {
01087                 if (IS_SET (ch->act, PLR_AUTOLOOT) && corpse
01088                     && corpse->contains)
01089                 {
01090                     return TRUE;    /* leave if corpse has treasure */
01091                 }
01092                 else
01093                 {
01094                     do_function (ch, &do_sacrifice, "corpse");
01095                 }
01096             }
01097         }
01098 
01099         return TRUE;
01100     }
01101 
01102     if (victim == ch)
01103         return TRUE;
01104 
01105     /*
01106      * Take care of link dead people.
01107      */
01108     if (!IS_NPC (victim) && victim->desc == NULL)
01109     {
01110         if (number_range (0, victim->wait) == 0)
01111         {
01112             do_function (victim, &do_recall, "");
01113             return TRUE;
01114         }
01115     }
01116 
01117     /*
01118      * Wimp out?
01119      */
01120     if (IS_NPC (victim) && dam > 0 && victim->wait < PULSE_VIOLENCE / 2)
01121     {
01122         if ((IS_SET (victim->act, ACT_WIMPY) && number_bits (2) == 0
01123              && victim->hit < victim->max_hit / 5)
01124             || (IS_AFFECTED (victim, AFF_CHARM) && victim->master != NULL
01125                 && victim->master->in_room != victim->in_room))
01126         {
01127             do_function (victim, &do_flee, "");
01128         }
01129     }
01130 
01131     if (!IS_NPC (victim)
01132         && victim->hit > 0
01133         && victim->hit <= victim->wimpy && victim->wait < PULSE_VIOLENCE / 2)
01134     {
01135         do_function (victim, &do_flee, "");
01136     }
01137 
01138     tail_chain ();
01139     return TRUE;
01140 }

Here is the call graph for this function:

void death_cry CHAR_DATA ch  ) 
 

Definition at line 1713 of file fight.c.

References act, create_object(), obj_data::description, room_index_data::exit, FORM_EDIBLE, FORM_POISON, free_string(), get_obj_index(), obj_data::in_room, IS_NPC, IS_SET, ITEM_FOOD, ITEM_TRASH, obj_data::item_type, MAX_STRING_LENGTH, obj_data::name, number_bits(), number_range(), obj_to_room(), OBJ_VNUM_BRAINS, OBJ_VNUM_GUTS, OBJ_VNUM_SEVERED_HEAD, OBJ_VNUM_SLICED_ARM, OBJ_VNUM_SLICED_LEG, OBJ_VNUM_TORN_HEART, PART_ARMS, PART_BRAINS, PART_GUTS, PART_HEAD, PART_HEART, PART_LEGS, obj_data::short_descr, str_dup(), obj_data::timer, exit_data::to_room, TO_ROOM, exit_data::u1, and obj_data::value.

Referenced by raw_kill().

01714 {
01715     ROOM_INDEX_DATA *was_in_room;
01716     char *msg;
01717     int door;
01718     int vnum;
01719 
01720     vnum = 0;
01721     msg = "You hear $n's death cry.";
01722 
01723     switch (number_bits (4))
01724     {
01725         case 0:
01726             msg = "$n hits the ground ... DEAD.";
01727             break;
01728         case 1:
01729             if (ch->material == 0)
01730             {
01731                 msg = "$n splatters blood on your armor.";
01732                 break;
01733             }
01734         case 2:
01735             if (IS_SET (ch->parts, PART_GUTS))
01736             {
01737                 msg = "$n spills $s guts all over the floor.";
01738                 vnum = OBJ_VNUM_GUTS;
01739             }
01740             break;
01741         case 3:
01742             if (IS_SET (ch->parts, PART_HEAD))
01743             {
01744                 msg = "$n's severed head plops on the ground.";
01745                 vnum = OBJ_VNUM_SEVERED_HEAD;
01746             }
01747             break;
01748         case 4:
01749             if (IS_SET (ch->parts, PART_HEART))
01750             {
01751                 msg = "$n's heart is torn from $s chest.";
01752                 vnum = OBJ_VNUM_TORN_HEART;
01753             }
01754             break;
01755         case 5:
01756             if (IS_SET (ch->parts, PART_ARMS))
01757             {
01758                 msg = "$n's arm is sliced from $s dead body.";
01759                 vnum = OBJ_VNUM_SLICED_ARM;
01760             }
01761             break;
01762         case 6:
01763             if (IS_SET (ch->parts, PART_LEGS))
01764             {
01765                 msg = "$n's leg is sliced from $s dead body.";
01766                 vnum = OBJ_VNUM_SLICED_LEG;
01767             }
01768             break;
01769         case 7:
01770             if (IS_SET (ch->parts, PART_BRAINS))
01771             {
01772                 msg =
01773                     "$n's head is shattered, and $s brains splash all over you.";
01774                 vnum = OBJ_VNUM_BRAINS;
01775             }
01776     }
01777 
01778     act (msg, ch, NULL, NULL, TO_ROOM);
01779 
01780     if (vnum != 0)
01781     {
01782         char buf[MAX_STRING_LENGTH];
01783         OBJ_DATA *obj;
01784         char *name;
01785 
01786         name = IS_NPC (ch) ? ch->short_descr : ch->name;
01787         obj = create_object (get_obj_index (vnum), 0);
01788         obj->timer = number_range (4, 7);
01789 
01790         sprintf (buf, obj->short_descr, name);
01791         free_string (obj->short_descr);
01792         obj->short_descr = str_dup (buf);
01793 
01794         sprintf (buf, obj->description, name);
01795         free_string (obj->description);
01796         obj->description = str_dup (buf);
01797 
01798         if (obj->item_type == ITEM_FOOD)
01799         {
01800             if (IS_SET (ch->form, FORM_POISON))
01801                 obj->value[3] = 1;
01802             else if (!IS_SET (ch->form, FORM_EDIBLE))
01803                 obj->item_type = ITEM_TRASH;
01804         }
01805 
01806         obj_to_room (obj, ch->in_room);
01807     }
01808 
01809     if (IS_NPC (ch))
01810         msg = "You hear something's death cry.";
01811     else
01812         msg = "You hear someone's death cry.";
01813 
01814     was_in_room = ch->in_room;
01815     for (door = 0; door <= 9; door++)
01816     {
01817         EXIT_DATA *pexit;
01818 
01819         if ((pexit = was_in_room->exit[door]) != NULL
01820             && pexit->u1.to_room != NULL && pexit->u1.to_room != was_in_room)
01821         {
01822             ch->in_room = pexit->u1.to_room;
01823             act (msg, ch, NULL, NULL, TO_ROOM);
01824         }
01825     }
01826     ch->in_room = was_in_room;
01827 
01828     return;
01829 }

Here is the call graph for this function:

void disarm CHAR_DATA ch,
CHAR_DATA victim
 

Definition at line 2394 of file fight.c.

References act, can_see_obj(), equip_char(), get_eq_char(), get_obj(), IS_NPC, IS_OBJ_STAT, ITEM_INVENTORY, ITEM_NODROP, ITEM_NOREMOVE, obj_from_char(), obj_to_char(), obj_to_room(), TO_CHAR, TO_NOTVICT, TO_ROOM, TO_VICT, WEAR_SECONDARY, and WEAR_WIELD.

Referenced by do_disarm().

02395 {
02396     OBJ_DATA *obj;
02397 
02398     if ((obj = get_eq_char (victim, WEAR_WIELD)) == NULL)
02399         return;
02400 
02401     if (IS_OBJ_STAT (obj, ITEM_NOREMOVE))
02402     {
02403         act ("$S weapon won't budge!{x", ch, NULL, victim, TO_CHAR);
02404         act ("$n tries to disarm you, but your weapon won't budge!{x",
02405              ch, NULL, victim, TO_VICT);
02406         act ("$n tries to disarm $N, but fails.{x", ch, NULL, victim,
02407              TO_NOTVICT);
02408         return;
02409     }
02410 
02411     act ("$n DISARMS you and sends your weapon flying!{x",
02412          ch, NULL, victim, TO_VICT);
02413     act ("You disarm $N!{x", ch, NULL, victim, TO_CHAR);
02414     act ("$n disarms $N!{x", ch, NULL, victim, TO_NOTVICT);
02415 
02416     obj_from_char (obj);
02417     if (get_eq_char(victim, WEAR_SECONDARY)) /* Damn it. Note to self: ch should != victim! */
02418     {
02419         OBJ_DATA *secondary;
02420         secondary = get_eq_char(victim, WEAR_SECONDARY);
02421         act ("$n throws $s secondary weapon into the air, and catches it in $s primary hand.",
02422                 victim, NULL, ch, TO_ROOM);
02423         act ("You toss your secondary weapon into the air, and catch it into your primary hand.",
02424                 ch, NULL,victim, TO_VICT);
02425         //remove_obj(victim, secondary);
02426         //equip_char(victim, secondary, WEAR_WIELD);
02427         obj_from_char(secondary);
02428         obj_to_char(secondary, victim);
02429         equip_char(victim, secondary, WEAR_WIELD);
02430     
02431     }
02432     if (IS_OBJ_STAT (obj, ITEM_NODROP) || IS_OBJ_STAT (obj, ITEM_INVENTORY))
02433         obj_to_char (obj, victim);
02434     else
02435     {
02436         obj_to_room (obj, victim->in_room);
02437         if (IS_NPC (victim) && victim->wait == 0 && can_see_obj (victim, obj))
02438             get_obj (victim, obj, NULL);
02439     }
02440 
02441     return;
02442 }

Here is the call graph for this function:

void do_backstab CHAR_DATA ch,
char *  argument
 

Definition at line 3132 of file