#include <ctype.h> #include <sys/types.h> #include <stdio.h> #include <syslog.h> #include "define.h" #include "struct.h" const char* condition_prep ( char_data* ); void msg_attack ( char_data*, char_data*, const char*, const char*, char ); void msg_other ( char_data*, char_data*, const char*, const char*, char ); /* * GENERAL MESSAGE ROUTINES */ void dam_local( char_data* victim, char_data* ch, int damage, const char* dt, const char* loc_name ) { char tmp [ TWO_LINES ]; char punct; const char* dam_name; char_data* rch; int flag; if( *loc_name == '\0' ) { dam_message( victim, ch, damage, dt, lookup( physical_index, damage ) ); return; } punct = ( damage <= 24 ? '.' : '!' ); dam_name = lookup( physical_index, damage ); victim->hit -= damage; sprintf( tmp, "%s's %s %s%s%s your %s%c\n\r", ch->Name( victim,1, TRUE ), dt, to_self( victim ), dam_name, normal( victim ), loc_name, punct ); corrupt( tmp, TWO_LINES, "Dam_Local" ); *tmp = toupper( *tmp ); send( victim, tmp ); if( victim->Seen( ch ) ) sprintf( tmp, "Your %s %s%s%s %s's %s%c", dt, by_self( ch ), dam_name, normal( ch ), victim->Name( ch, 1, TRUE ), loc_name, punct ); else sprintf( tmp, "Your %s %s%s%s someone%c", dt, by_self( ch ), dam_name, normal( ch ), punct ); corrupt( tmp, TWO_LINES, "Dam_Local" ); strcat_cond( tmp, ch, victim ); flag = ( victim->pcdata == NULL && !is_set( &victim->status, STAT_PET ) ? MSG_DAMAGE_MOBS : MSG_DAMAGE_PLAYERS ); for( int i = 0; i < *ch->array; i++ ) { if( ( rch = character( ch->array->list[i] ) ) == NULL || rch == ch || rch == victim || rch->link == NULL || !is_set( &rch->pcdata->message, flag ) || !rch->Can_See( ) ) continue; if( victim->Seen( rch ) ) sprintf( tmp, "%s's %s %s%s%s %s's %s%c", ch->Name( rch, 1, TRUE ), dt, damage_color( rch, ch, victim ), dam_name, normal( rch ), victim->Seen_Name( rch ), loc_name, punct ); else sprintf( tmp, "%s's %s %s%s%s someone%c", ch->Name( rch ), dt, damage_color( rch, ch, victim ), dam_name, normal( rch ), punct ); corrupt( tmp, TWO_LINES, "Dam_Local" ); *tmp = toupper( *tmp ); strcat_cond( tmp, rch, victim ); } victim->hit += damage; return; } void dam_message( char_data* victim, char_data* ch, int damage, const char* dt, const char* word ) { char tmp [ ONE_LINE ]; int i; char punct; victim->hit -= damage; strcpy( tmp, dt ); if( ( i = strlen( tmp ) ) > 2 && tmp[i-2] == '\n' ) tmp[i-2] = '\0'; punct = ( damage <= 24 ? '.' : '!' ); if( ch == NULL || *dt == '*' ) msg_other( victim, ch, *tmp == '*' ? &tmp[1] : tmp, word, punct ); else msg_attack( victim, ch, tmp, word, punct ); victim->hit += damage; return; } void msg_attack( char_data* victim, char_data* ch, const char* dt, const char* word, char punct ) { char tmp [ MAX_INPUT_LENGTH ]; char_data* rch; int flag; sprintf( tmp, "Your %s %s%s%s %s%c", dt, by_self( ch ), word, normal( ch ), victim->Name( ch ), punct ); strcat_cond( tmp, ch, victim ); sprintf( tmp, "%s's %s %s%s%s you%c\n\r", ch->Name( victim ), dt, to_self( victim ), word, normal( victim ), punct ); *tmp = toupper( *tmp ); send( tmp, victim ); flag = ( victim->pcdata == NULL && !is_set( &victim->status, STAT_PET ) ? MSG_DAMAGE_MOBS : MSG_DAMAGE_PLAYERS ); for( int i = 0; i < *ch->array; i++ ) { if( ( rch = character( ch->array->list[i] ) ) == NULL || rch == ch || rch == victim || rch->link == NULL || !is_set( &rch->pcdata->message, flag ) || !rch->Can_See( ) ) continue; sprintf( tmp, "%s's %s %s%s%s %s%c", ch->Name( rch ), dt, damage_color( rch, ch, victim ), word, normal( rch ), victim->Name( rch ), punct ); *tmp = toupper( *tmp ); strcat_cond( tmp, rch, victim ); } return; } void msg_other( char_data* victim, char_data* ch, const char* dt, const char* word, char punct ) { char tmp [ TWO_LINES ]; char_data* rch; sprintf( tmp, "%s %s%s%s you%c\n\r", dt, to_self( victim ), word, normal( victim ), punct ); corrupt( tmp, TWO_LINES, "Msg_Other" ); *tmp = toupper( *tmp ); send( tmp, victim ); for( int i = 0; i < *victim->array; i++ ) { if( ( rch = character( victim->array->list[i] ) ) == NULL || rch == victim || !rch->Can_See( ) ) continue; sprintf( tmp, "%s %s%s%s %s%c", dt, damage_color( rch, ch, victim ), word, normal( rch ), victim->Name( rch ), punct ); corrupt( tmp, TWO_LINES, "Msg_Other" ); *tmp = toupper( *tmp ); strcat_cond( tmp, rch, victim ); } return; } /* * CONDITION ROUTINES */ void strcat_cond( char* tmp, char_data* ch, char_data* victim ) { const char* cond_word = condition_word( victim ); bool visible = TRUE; int length = 0; for( int i = 0; tmp[i] != '\0'; i++ ) { if( visible ) { if( tmp[i] == '' ) visible = FALSE; else length++; } else if( tmp[i] == 'm' ) visible = TRUE; } send( ch, "%s%s[ %s ]\n\r", tmp, length+strlen( cond_word ) > 74 ? "\n\r" : " ", cond_word ); return; } const char* condition_prep( char_data *ch ) { int percent = (100*ch->hit)/ch->max_hit; if( ch->hit <= -10 ) return "is"; if( percent >= 100 ) return "is in"; else if( percent >= 90 ) return "is"; else if( percent >= 80 ) return "has a"; else if( percent >= 70 ) return "has"; else if( percent >= 60 ) return "has"; else if( percent >= 50 ) return "is"; else if( percent >= 40 ) return "has"; else if( percent >= 30 ) return "is"; else if( percent >= 20 ) return "is"; else if( percent >= 10 ) return "is"; else if( percent >= 0 ) return "is"; return "is"; } const char* condition_word( char_data* ch ) { int percent = (100*ch->hit)/ch->max_hit; if( ch->hit <= -11 ) return "DEAD!"; if( percent >= 100 ) return "perfect health"; else if( percent >= 90 ) return "slightly scratched"; else if( percent >= 80 ) return "few bruises"; else if( percent >= 70 ) return "some cuts"; else if( percent >= 60 ) return "several wounds"; else if( percent >= 50 ) return "badly wounded"; else if( percent >= 40 ) return "many nasty wounds"; else if( percent >= 30 ) return "bleeding freely"; else if( percent >= 20 ) return "covered in blood"; else if( percent >= 10 ) return "leaking guts"; else if( percent >= 0 ) return "mostly dead"; return "dying"; } const char* condition_short( char_data* ch, char_data* victim ) { if( victim == NULL ) return "-"; if( victim->array != ch->array || !victim->Seen( ch ) ) return "??"; return condition_short( victim ); } const char* condition_short( char_data* ch ) { int percent; if( ch->hit <= -11 ) return "DEAD!"; percent = (100*ch->hit)/ch->max_hit; if( percent >= 100 ) return "perfect"; else if( percent >= 90 ) return "scratched"; else if( percent >= 80 ) return "bruised"; else if( percent >= 70 ) return "cut"; else if( percent >= 60 ) return "wounded"; else if( percent >= 50 ) return "badly wounded"; else if( percent >= 40 ) return "nastily wounded"; else if( percent >= 30 ) return "bleeding freely"; else if( percent >= 20 ) return "covered in blood"; else if( percent >= 10 ) return "leaking guts"; else if( percent >= 0 ) return "mostly dead"; return "dying"; } /* * GENERAL INFLICT ROUTINE */ bool inflict( char_data* victim, char_data* ch, int dam, char* dt ) { if( victim->position == POS_DEAD ) return TRUE; if( dam > 1000 ) { bug( "Inflict: more than 1000 points!" ); dam = 1000; } else if( dam <= 0 ) return FALSE; record_damage( victim, ch, dam ); victim->hit -= dam; update_pos( victim ); update_max_move( victim ); set_bit( &victim->status, STAT_WIMPY ); if( victim->position == POS_SLEEPING ) { strip_affect( victim, AFF_SLEEP ); send( victim, "You are suddenly awakened by the feeling of pain.\n\r" ); send_seen( victim, "%s wakes up.\n\r", victim ); victim->position = POS_RESTING; renter_combat( victim ); } /* if( IS_AFFECTED( victim, AFF_CONFUSED ) && dam > number_range( 0, 100 ) ) { strip_affect( victim, AFF_CONFUSED ); send( "You are knocked to your senses.\n\r", victim ); act( "$n is knocked to $s senses.", victim, NULL, NULL, TO_ROOM ); victim->fighting = NULL; victim->aggressive = NULL; for( rch = victim->in_room->people; rch != NULL; rch = rch->next_in_room ) if( IS_NPC( rch ) && !IS_SET( rch->status, STAT_PET ) ) { if( rch->fighting == ch ) rch->fighting = NULL; if( rch->aggressive == ch ) rch->aggressive = NULL; } } */ switch( victim->position ) { case POS_MORTAL: send( victim, "You are mortally wounded, and will die soon, if not aided.\n\r" ); send_seen( victim, "%s is mortally wounded, and will die soon, if not aided.\n\r", victim ); break; case POS_INCAP: send( victim, "You are incapacitated and will slowly die, if not aided.\n\r" ); send_seen( victim, "%s is incapacitated and will slowly die, if not aided.\n\r", victim ); break; case POS_STUNNED: send( victim, "You are stunned, but will probably recover.\n\r" ); send_seen( victim, "%s is stunned, but will probably recover.\n\r", victim ); break; case POS_DEAD: death_message( victim ); break; default: if( dam > victim->max_hit/4 ) send( "That really did HURT!\n\r", victim ); if( victim->pcdata != NULL && victim->hit < victim->max_hit/4 && is_set( &victim->pcdata->message, MSG_BLEEDING ) ) send( victim, "You sure are BLEEDING!\n\r" ); break; } if( victim->rider != NULL && victim->position < POS_FIGHTING ) { send( victim->rider, "You are thrown to the ground as your mount is %s.\n\r", victim->position == POS_DEAD ? "killed" : "incapacitated" ); victim->rider->position = POS_RESTING; victim->rider->mount = NULL; victim->rider = NULL; } if( ch != NULL && ch->species != NULL ) ch->species->damage += dam; if( victim->position == POS_DEAD ) { death( victim, ch, dt ); return TRUE; } return FALSE; } /* * GLANCE ROUTINES */ void do_glance( char_data* ch, char* argument ) { char_data* victim; if( *argument == '\0' ) { send( ch, "Who do you want to glance at?\n\r" ); return; } if( ( victim = one_character( ch, argument, "glance", ch->array ) ) == NULL ) return; glance( ch, victim ); return; } void glance( char_data* ch, char_data* victim ) { if( victim == ch ) { page( ch, "Your condition is %s.\n\r", condition_word( ch ) ); return; } page( ch, "%s %s %s%s%s%c\n\r", victim->Seen_Name( ch ), condition_prep( victim ), color_scale( ch, 6-6*victim->hit/victim->max_hit ), condition_word( victim ), normal( ch ), victim->hit > 0 ? '.' : '!' ); return; } /* * SPAM ROUTINES */ void spam_char( char_data* ch, const char* text ) { if( ch->link == NULL || !is_set( &ch->pcdata->message, MSG_MISSES ) ) return; send( ch, text ); return; } void spam_room( const char* text, char_data* ch, char_data* victim ) { char tmp [ TWO_LINES ]; char_data* rch; for( int i = 0; i < *ch->array; i++ ) { if( ( rch = character( ch->array->list[i] ) ) == NULL || rch->link == NULL || rch == ch || rch == victim || rch->position <= POS_SLEEPING || !is_set( &rch->pcdata->message, MSG_MISSES ) ) continue; sprintf( tmp, text, ch->Name( rch ), victim == NULL ? "[BUG]" : victim->Name( rch ) ); corrupt( tmp, TWO_LINES, "Spam_Room" ); *tmp = toupper( *tmp ); send( tmp, rch ); } return; } /* * PHYSICAL DAMAGE ROUTINES */ index_data physical_index [] = { { "misses", "miss", 0 }, { "scratches", "scratch", 1 }, { "grazes", "graze", 2 }, { "hits", "hit", 4 }, { "injures", "injure", 6 }, { "wounds", "wound", 10 }, { "mauls", "maul", 15 }, { "decimates", "decimate", 21 }, { "devastates", "devastate", 28 }, { "maims", "maim", 35 }, { "SAVAGES", "SAVAGE", 45 }, { "CRIPPLES", "CRIPPLE", 55 }, { "MUTILATES", "MUTILATE", 70 }, { "DISEMBOWELS", "DISEMBOWEL", 85 }, { "* DISMEMBERS *", "* DISMEMBER *", 100 }, { "* EVISCERATES *", "* EVISCERATE *", 120 }, { "* MASSACRES *", "* MASSACRE *", 145 }, { "* PULVERIZES *", "* PULVERIZE *", 170 }, { "** DEMOLISHES **", "** DEMOLISH **", 200 }, { "** EXTIRPATES **", "** EXTIRPATE **", 240 }, { "*** OBLITERATES ***", "*** OBLITERATE ***", 280 }, { "*** ERADICATES ***", "*** ERADICATE ***", 330 }, { "*** ANNIHILATES ***", "*** ANNIHILATE ***", -1 } }; bool damage_physical( char_data* victim, char_data* ch, int damage, const char* string, bool plural ) { dam_message( victim, ch, damage, string, lookup( physical_index, damage, plural ) ); return inflict( victim, ch, damage, "physical damage" ); } bool damage_magic( char_data* victim, char_data* ch, int damage, const char* string, bool plural ) { damage *= 100-victim->shdata->resist[RES_MAGIC]; damage /= 100; dam_message( victim, ch, damage, string, lookup( physical_index, damage, plural ) ); return inflict( victim, ch, damage, "shock" ); } bool damage_mind( char_data* victim, char_data* ch, int damage, const char* string, bool plural ) { damage *= 100-victim->shdata->resist[RES_MIND]; damage /= 100; dam_message( victim, ch, damage, string, lookup( physical_index, damage, plural ) ); return inflict( victim, ch, damage, "shock" ); }