/*--------------------------------------------------------------------------*
* ** WolfPaw 3.0 ** *
*--------------------------------------------------------------------------*
* WolfPaw 3.0 (c) 1997 - 1999 by Dale Corse *
*--------------------------------------------------------------------------*
* The WolfPaw Coding Team is headed by: Greywolf *
* With the Assitance from: Callinon, Dhamon, Sentra, Wyverns, Altrag *
* Scryn, Thoric, Justice, Tricops and Brogar. *
*--------------------------------------------------------------------------*
* Based on SMAUG 1.2a. Copyright 1994 - 1996 by Derek Snider *
* SMAUG Coding Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, *
* Swordbearer, Gorog, Grishnakh and Tricops. *
*--------------------------------------------------------------------------*
* Merc 2.1 Diku MUD Improvments (C) 1992 - 1993 by Michael Chastain, *
* Michael Quan, and Michael Tse. *
* Original Diku MUD (C) 1990 - 1991 by Sebastian Hammer, Michael Seifert, *
* Hans Hendrik Strfeldt, Tom Madsen, and Katja Nyboe. *
*--------------------------------------------------------------------------*
* Death Handling Module *
*--------------------------------------------------------------------------*/
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"
bool death_handler args( ( CHAR_DATA *ch, CHAR_DATA *victim, bool npcvict ) );
void kombat_death args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void war_death args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void challenge_death args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void assassin_death args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void bounty_death args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
CHALLENGE_DATA *find_challenge args( ( CHAR_DATA *ch ) );
ARENA_DATA *find_arena args( ( CHALLENGE_DATA *challenge ) );
ARENA_DATA *find_arena_by_challenge args( ( CHALLENGE_DATA *challenge ) );
void raw_kill args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void remove_char args( ( CHAR_DATA *ch ) );
void do_char_ressurect args ( ( CHAR_DATA *ch ) );
void do_char_notressurect args ( ( CHAR_DATA *ch ) );
void ego_update args( ( CHAR_DATA *ch, CHAR_DATA *victim, bool gain ) );
char *get_ego_text args( ( CHAR_DATA *ch ) );
CHAR_DATA *get_char args( ( char *name ) );
void create_ghost( CHAR_DATA *ch);
void ctf_death( CHAR_DATA *killer, CHAR_DATA *victim );
void ctf_channel( char *argument );
void flag_control( CHAR_DATA *ch, int flag, int type );
/*
* Handles what happens when a Character Dies --GW
*/
bool death_handler( CHAR_DATA *ch, CHAR_DATA *victim, bool npcvict )
{
char sex[MSL];
if ( !ch || !victim )
{
bug("Death_Handler: NULL ch || Victim!",0);
return FALSE;
}
if ( !IS_NPC(ch) && !IS_NPC(victim) &&
IS_SET(victim->pcdata->flags,PCFLAG_KOMBAT) )
{
kombat_death( ch, victim );
return TRUE;
}
/* CTF Death */
if ( !IS_NPC(victim) && IS_SET(victim->pcdata->flagstwo, MOREPC_CTF))
{
ctf_death( ch, victim );
return TRUE;
}
/* Need 2 Challenge checks .. make sure we catch things both ways .. and dont
have a character dying for real in the arena.. --GW */
if( !IS_NPC(victim) && ((!IS_NPC(victim) && IS_SET(victim->pcdata->flags,PCFLAG_CHALLENGER)) ||
(!IS_NPC(ch) && IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGER))) &&
( in_arena(ch) && in_arena(victim) ) )
{
challenge_death( ch, victim );
return TRUE;
}
if( !IS_NPC(victim) && ((!IS_NPC(victim) && IS_SET(victim->pcdata->flags,PCFLAG_CHALLENGED)) ||
(!IS_NPC(ch) && IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGED))) &&
( in_arena(ch) && in_arena(victim) ) )
{
challenge_death( ch, victim );
return TRUE;
}
if ( !IS_NPC(victim) && !IS_NPC(ch) &&
victim->position == POS_DEAD && (IS_SET(victim->pcdata->flagstwo,MOREPC_WAR)))
{
war_death( ch, victim );
return TRUE;
}
if ( !IS_NPC(victim) && (get_life_protection_char(victim)==TRUE) )
return TRUE;
if ( !IS_NPC(ch) && !IS_NPC(victim) && IS_SET(victim->pcdata->flags, PCFLAG_ASSASSIN ) && ch != victim )
{
assassin_death( ch, victim );
return TRUE;
}
if ( !IS_NPC(ch) && IS_AFFECTED(victim, AFF_BOUNTY) && ch != victim )
bounty_death( ch, victim );
if ( !IS_NPC(victim) && IS_NPC(ch) )
{
if ( victim != ch )
{
sprintf( log_buf, "&R[DEATH]&W %s Slaughtered by %s!",
victim->name,(IS_NPC(ch) ? ch->short_descr : ch->name));
echo_to_all(AT_PLAIN,log_buf,ECHOTAR_ALL);
}
else
{
sprintf( log_buf, "&R[DEATH]&W %s bleeds to death!",victim->name);
echo_to_all(AT_PLAIN,log_buf,ECHOTAR_ALL);
}
}
if ( !IS_NPC(victim) && !IS_NPC(ch) )
{
if ( victim != ch )
{
sprintf( log_buf, "&R[PLAYER KILL]&W %s just got terminally inconvienced by %s!",
victim->name,(IS_NPC(ch) ? ch->short_descr : ch->name));
echo_to_all(AT_PLAIN,log_buf,ECHOTAR_ALL);
add_timer( victim, TIMER_PKILLED, 115, NULL, 0 );
ch->pcdata->pkills++;
victim->pcdata->pdeaths++;
if ( ch->pcdata->clan && victim->pcdata->clan )
update_clan_pk_data(ch->pcdata->clan,victim->pcdata->clan);
}
else
{
switch(victim->sex)
{
case SEX_MALE:
sprintf(sex,"him");
break;
case SEX_FEMALE:
sprintf(sex,"her");
break;
case SEX_NEUTRAL:
sprintf(sex,"it");
break;
}
sprintf( log_buf, "&C[BONEHEAD]&W %s killed %sself!",victim->name,
sex);
echo_to_all(AT_PLAIN,log_buf,ECHOTAR_ALL);
}
}
if ( !npcvict )
{
sprintf( log_buf, "%s killed by %s at %d",
victim->name,
(IS_NPC(ch) ? ch->short_descr : ch->name),
victim->in_room->vnum );
log_string( log_buf );
to_channel( log_buf, CHANNEL_MONITOR, "[ ** ",LEVEL_IMMORTAL);
}
stop_fighting(ch, TRUE);
raw_kill( ch,victim );
return FALSE;
}
void kombat_death( CHAR_DATA *ch, CHAR_DATA *victim )
{
int num_kom=0;
char buf[MSL];
send_to_char("&RYou &Bare &RDEAD &BSorry...\n\r",victim);
stop_fighting(ch,TRUE);
char_from_room(victim);
char_to_room(victim,get_room_index(30601,1));
sprintf(buf,"&R<&BMortal Kombat&R>&B %s has been &RSlain&B!",
capitalize(victim->name) );
echo_to_all(AT_PLAIN,buf,ECHOTAR_ALL);
ch->pcdata->num_kombatants++;
REMOVE_BIT( victim->pcdata->flags, PCFLAG_KOMBAT );
victim->hit = victim->max_hit;
victim->position = 8;
update_pos(victim);
do_save(victim,"");
num_kom = number_kombat( );
if( num_kom == 1 )
{
sprintf(buf,"&R<&BMortal Kombat&R>&R %s &Bis &RViKtorious&B!",
capitalize(ch->name));
echo_to_all(AT_PLAIN,buf,ECHOTAR_ALL);
char_from_room(ch);
char_to_room(ch,get_room_index(30601,1) );
REMOVE_BIT( ch->pcdata->flags, PCFLAG_KOMBAT );
ch->pcdata->num_kombats_won++;
REMOVE_BIT( kombat->bits, KOMBAT_ON );
REMOVE_BIT( kombat->bits, KOMBAT_DUAL );
REMOVE_BIT( kombat->bits, KOMBAT_ADVANCED );
REMOVE_BIT( kombat->bits, KOMBAT_NODRAGON );
REMOVE_BIT( kombat->bits, KOMBAT_NOAVATAR );
send_to_char("Your Quest Points Raise by 20!\n\r",ch);
ch->pcdata->quest_curr += 20;
ch->pcdata->quest_accum += 20;
do_save(ch,"");
}
return;
}
void assassin_death( CHAR_DATA *ch, CHAR_DATA *victim )
{
send_to_char("You are NO longer an ASSASSIN the price has been paid!", victim);
REMOVE_BIT(victim->pcdata->flags, PCFLAG_ASSASSIN);
do_save( victim, "" );
stop_fighting(victim,TRUE);
char_from_room(victim);
char_to_room(victim,get_room_index(30601,1));
victim->hit = victim->max_hit;
update_pos(victim);
return;
}
void bounty_death( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MSL];
ch->gold += victim->pcdata->bounty;
send_to_char("You have recieved payment for your good work.\n\r",ch);
sprintf(buf,"[ASSASSINATION] %s has completed the bounty on %s's head.\n\r",
ch->name, victim->name);
echo_to_all( AT_BLOOD,buf,ECHOTAR_ALL );
SET_BIT(ch->pcdata->flags, PCFLAG_ASSASSIN);
xREMOVE_BIT(victim->affected_by, AFF_BOUNTY);
send_to_char("You are now an ASSASSIN!\n\r", ch );
do_save( ch, "");
stop_fighting(victim,TRUE);
char_from_room(victim);
char_to_room(victim,get_room_index(30601,1));
victim->hit = victim->max_hit;
return;
}
void war_death( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MSL];
sprintf(buf,"(WAR) -- %s has been SLAUGHTERED!!!!",capitalize(victim->name));
echo_to_all(AT_BLOOD,buf,ECHOTAR_ALL);
send_to_char("Your OUT OF HERE!!!!\n\r",victim);
stop_fighting(ch, TRUE);
stop_fighting(victim, TRUE);
SET_BIT(victim->pcdata->flagstwo, MOREPC_OUTWAR);
REMOVE_BIT(victim->pcdata->flagstwo, MOREPC_WAR);
/* reset the players stats */
SET_BIT( victim->position, POS_RESTING );
victim->hit = victim->max_hit;
update_pos( victim );
return;
}
void challenge_death(CHAR_DATA *ch, CHAR_DATA *victim)
{
CHALLENGE_DATA *challenge;
ARENA_DATA *arena;
char buf[MSL];
DESCRIPTOR_DATA *d;
CHAR_DATA *winner, *loser;
if(in_arena( ch )
&& in_arena( victim ) )
{
challenge = find_challenge( ch );
arena = find_arena_by_challenge(challenge);
/*
* Support for if the person kills themself eg: bleeds to death --GW
*/
if ( ch == victim )
{
if ( !str_cmp( ch->name, challenge->challenger ) )
winner=get_char(challenge->challenged);
else
winner=get_char(challenge->challenger);
loser=ch;
}
else
{
winner=ch;
loser=victim;
}
/*
* Added Support for use of Charmed Mobies in the Arena .. weather or not there actually
* following there master or not --GW
*/
if ( IS_NPC(ch) ) /* The killer would be the mob . thats what kills the MUD */
{
if ( ch->master ) /* Following a Master - Easy */
winner = ch->master;
else /* OK folks .. we have a Loose mobile here..... oy! */
{
CHAR_DATA *tmp, *tmp_next, *tmp2=NULL;
bool found;
/*
* Unfortunetly we have to do this the long way - as Challenge could be NULL, and that
* would bomb .. so .. well have to scan all the players online and find them ones in
* the arena, and use those.. we can use the char list, as in this code .. mobs are in
* the zone data .. not in the first/last_char lists.
* Note: We only need 1 guy to do a challenge lookup.. not 2.. the challenge arrays will do the rest
* --GW
*/
found = FALSE;
for ( tmp=first_char; tmp; tmp = tmp_next )
{
tmp_next=tmp->next;
/* Found the first guy */
if ( in_arena(tmp) && !IS_NPC(tmp) &&
(IS_SET(tmp->pcdata->flags, PCFLAG_CHALLENGED) ||
IS_SET(tmp->pcdata->flags, PCFLAG_CHALLENGER)))
{
/* We have to re-lookup the arena there using, and the challenge
data, as we may have changed characters --GW */
challenge = find_challenge( tmp );
if ( !challenge )
bug("NULL CHALLENGE!");
arena = find_arena_by_challenge(challenge);
found = TRUE;
break;
}
}
if ( !found )
bug("Challenge Not Found! We are GOING DOWN!!!",0);
tmp2=get_char(challenge->challenger);
if ( !str_cmp( victim->name, tmp2->name ) ) /* is it the Challenger thats dead? */
{
winner=get_char(challenge->challenged);
victim=tmp2;
}
else /* Ok its the other fool */
{
winner=tmp2;
victim=get_char(challenge->challenged);
}
}
/* We have to re-lookup the arena there using, and the challenge data, as we may have changed
characters --GW */
/* Note it is needed in BOTH places - trust me =) --GW */
challenge = find_challenge( winner );
arena = find_arena_by_challenge(challenge);
}
ch=winner;
victim=loser;
if ( victim == ch && IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGER ) )
{
if((victim=get_char_world(ch,challenge->challenged))==NULL)
{
victim = ch;
}
}
sprintf(buf,"&r[CHALLENGE]&W %s has KICKED %s's BUTT!!!\n\r",
ch->name, victim->name);
echo_to_all( AT_PLAIN,buf,ECHOTAR_ALL );
ch->pcdata->awins += 1;
victim->pcdata->alosses += 1;
pk_champ_check(ch,victim);
for ( d = first_descriptor; d; d = d->next )
{
if( d->character && d->character->pcdata->gladiator && ch )
{
if ( d->character->pcdata->gladiator == ch->name )
{
d->character->gold += (d->character->pcdata->plr_wager * 2);
send_to_char("&R[&BGAMBLE&R]&W You won!\n\r",d->character);
/* reset the info */
d->character->pcdata->gladiator = NULL;
d->character->pcdata->plr_wager = 0;
}
if(d->character->pcdata->gladiator != ch->name
&& d->character->pcdata->plr_wager >= 1)
{
d->character->gold -= d->character->pcdata->plr_wager;
send_to_char("&R[&BGAMBLE&R]&W You lose!\n\r",d->character);
/* reset the betting info info */
d->character->pcdata->gladiator = NULL;
d->character->pcdata->plr_wager = 0;
}
}
}
/* now move both fighters out of arena
and back to the regular "world"
be sure to define ROOM_VNUM_AWINNER and ROOM_VNUM_ALOSER
*/
/* Arena Viewers gotta go now ..--GW */
stop_viewers( );
stop_fighting(ch,TRUE);
char_from_room(victim);
char_to_room(victim,get_room_index(30601,1));
do_look(victim,"auto");
char_from_room(ch);
char_to_room(ch,get_room_index(30602,1));
do_look(ch,"auto");
if(IS_SET(ch->pcdata->flags, PCFLAG_CHALLENGER))
REMOVE_BIT(ch->pcdata->flags, PCFLAG_CHALLENGER);
else if(IS_SET(victim->pcdata->flags, PCFLAG_CHALLENGER))
REMOVE_BIT(victim->pcdata->flags, PCFLAG_CHALLENGER);
if(IS_SET(victim->pcdata->flags, PCFLAG_CHALLENGED))
REMOVE_BIT(victim->pcdata->flags, PCFLAG_CHALLENGED);
else if(IS_SET(ch->pcdata->flags, PCFLAG_CHALLENGED))
REMOVE_BIT(ch->pcdata->flags, PCFLAG_CHALLENGED);
/* reset the two players stats */
SET_BIT( victim->position, POS_RESTING );
SET_BIT( ch->position, POS_RESTING );
ch->hit = ch->max_hit;
victim->hit = victim->max_hit;
update_pos( victim );
if ( !challenge )
return;
UNLINK(challenge, first_challenge, last_challenge, next, prev );
DISPOSE(challenge);
arena->in_use = FALSE; /* Clear the Arena */
}
return;
}
void raw_kill( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MAX_STRING_LENGTH];
if ( !ch )
{
bug( "raw_kill: null char!",0);
return;
}
if ( !victim )
{
bug( "raw_kill: null victim!", 0 );
return;
}
/* backup in case hp goes below 1 */
if (!IS_NPC(victim) && NOT_AUTHED(victim))
{
bug( "raw_kill: killing unauthed", 0 );
return;
}
stop_fighting( victim, TRUE );
stop_fighting( ch, TRUE );
if ( !IS_NPC(ch) )
ch->alignment = align_compute( ch, victim ); /* Hopefully this'll
correct our little
bug -- Cal */
mprog_death_trigger( ch, victim );
if ( char_died(victim) )
return;
rprog_death_trigger( ch, victim );
if ( char_died(victim) )
return;
/* Nuke auction if they are auctioning and Die --GW */
if ( !IS_NPC(victim) && (auction->item != NULL && auction->seller != NULL &&
auction->buyer != NULL &&
( !str_cmp( auction->buyer->name, victim->name ) ||
!str_cmp( auction->seller->name, victim->name ) ) ) )
{
sprintf(buf,"&R%s has been killed, gold and auction object have been returned.&W",
victim->name);
talk_auction(buf,TRUE);
obj_to_char( auction->item, auction->seller );
auction->buyer->real_gold += auction->bet;
auction->item = NULL;
}
if ( !victim->died_in_room )
victim->died_in_room = victim->in_room;
/* Follow */
die_follower(victim);
make_corpse( victim, ch, FALSE );
make_blood( ch );
/* Ghosts --GW */
if ( !IS_NPC(victim) )
create_ghost(victim);
if ( IS_NPC(victim) )
{
victim->pIndexData->killed++;
extract_char( victim, TRUE );
victim = NULL;
return;
}
ego_update( victim, ch, FALSE );
extract_char( victim, FALSE );
if ( !victim )
{
bug( "oops! raw_kill: extract_char destroyed pc char", 0 );
return;
}
while ( victim->first_affect )
affect_remove( victim, victim->first_affect );
xSET_BITS(victim->affected_by, race_table[victim->race]->affected);
victim->resistant = 0;
victim->susceptible = 0;
victim->immune = 0;
victim->carry_weight= 0;
victim->armor = 100;
victim->mod_str = 0;
victim->mod_dex = 0;
victim->mod_wis = 0;
victim->mod_int = 0;
victim->mod_con = 0;
victim->mod_cha = 0;
victim->mod_lck = 0;
victim->damroll = 0;
victim->hitroll = 0;
victim->mental_state = -10;
victim->alignment = URANGE( -1000, victim->alignment, 1000 );
victim->saving_spell_staff = 0;
victim->position = POS_RESTING;
victim->hit = UMAX( 1, victim->hit );
victim->mana = UMAX( 1, victim->mana );
victim->move = UMAX( 1, victim->move );
victim->exp -= (victim->exp/2);
if (victim->exp < 0 )
victim->exp = 0;
if ( IS_SET( sysdata.save_flags, SV_DEATH ) )
save_char_obj( victim );
do_char_notressurect(victim);
char_to_room(victim,get_room_index(30601,1));
return;
}
/*
* Improved Death_cry contributed by Diavolo.
* Additional improvement by Thoric (and removal of turds... sheesh!)
*/
void death_cry( CHAR_DATA *ch )
{
ROOM_INDEX_DATA *was_in_room;
char *msg;
EXIT_DATA *pexit;
int vnum;
int cnt=0;
if ( !ch )
{
bug( "DEATH_CRY: null ch!", 0 );
return;
}
msg = NULL;
vnum = 0;
switch ( number_bits( 4 ) )
{
default: msg = "You hear $n's blood chilling last scream!"; break;
case 0: msg = "$n hits the ground ... DEAD."; break;
case 1: msg = "$n splatters blood on your armor."; break;
case 2: if ( HAS_BODYPART(ch, PART_GUTS) )
{
msg = "$n's guts spill all over the ground.";
vnum = OBJ_VNUM_SPILLED_GUTS;
}
else
msg = "$n collapses lifeless to the ground.";
break;
case 3: if ( HAS_BODYPART(ch, PART_HEAD) )
{
msg = "$n's severed head plops on the ground.";
vnum = OBJ_VNUM_SEVERED_HEAD;
}
else
msg = "You hear $n's death cry.";
break;
case 4: if ( HAS_BODYPART(ch, PART_HEART) )
{
msg = "$n's heart is torn from $s chest.";
vnum = OBJ_VNUM_TORN_HEART;
}
else
msg = "$n collapses lifeless to the ground.";
break;
case 5: if ( HAS_BODYPART(ch, PART_ARMS) )
{
msg = "$n's arm is sliced from $s dead body.";
vnum = OBJ_VNUM_SLICED_ARM;
}
else
msg = "You hear $n's death cry.";
break;
case 6: if ( HAS_BODYPART( ch, PART_LEGS) )
{
msg = "$n's leg is sliced from $s dead body.";
vnum = OBJ_VNUM_SLICED_LEG;
}
else
msg = "$n collapses lifeless to the ground.";
break;
}
act( AT_CARNAGE, msg, ch, NULL, NULL, TO_ROOM );
if ( vnum )
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *obj;
char *name;
ZONE_DATA *zone;
zone = find_zone(1);
name = IS_NPC(ch) ? ch->short_descr : ch->name;
obj = create_object(get_obj_index(vnum,(int)zone->number ),0,zone);
if ( !obj )
return;
obj->timer = number_range( 4, 7 );
sprintf( buf, obj->short_descr, name );
STRFREE( obj->short_descr );
obj->short_descr = STRALLOC( buf );
sprintf( buf, obj->description, name );
STRFREE( obj->description );
obj->description = STRALLOC( buf );
obj = obj_to_room( obj, ch->in_room );
}
if ( IS_NPC(ch) )
msg = "You hear something's blood chilling last scream!";
else
msg = "You hear someone's blood chilling last scream!";
was_in_room = ch->in_room;
cnt=0;
for ( pexit = was_in_room->first_exit; pexit; pexit = pexit->next )
{
if ( cnt >= 10 )
break;
if ( pexit->to_room
&& pexit->to_room != was_in_room )
{
cnt++;
char_from_room(ch);
char_to_room(ch,pexit->to_room);
act( AT_CARNAGE, msg, ch, NULL, NULL, TO_ROOM );
}
}
return;
}
/*
* The Grim Reaper! Who Else! MuHAHAHAHA! --GW
*/
void grim_reaper( CHAR_DATA *victim, bool olddeath )
{
char message[MSL];
/* Alignment Based Death Messages, vs. $n is dead.. much nicer
* I plan to do tons to the death system, and this is where
* the action will be (this file)--GW
*/
if ( !olddeath )
{
if ( IS_EVIL(victim) )
{
sprintf(message,
"\n\r"
"&BA Pulsing Bright Gateway slowly opens above $n.&W\n\r"
"&BYou see the spirit of $n before you, giving you a&W\n\r"
"&Blook of pure &RTerror&B as $e is dragged into the&W\n\r"
"&BPortal, by the Minions of Hell itself...\n\r"
"\n\r"
"&RInside your mind, you hear the Raspy Voice of the Reaper&W\n\r"
"&RHe says '&WThank-you&R'&W\n\r"
"\n\r");
}
else if ( IS_GOOD(victim) || IS_NEUTRAL(victim) )
{
sprintf(message,
"\n\r"
"&WYou see the soul of $n slowly rise from $s body,&W\n\r"
"&Wthe soul turn's to you, with a happy joyous look&W\n\r"
"&Wupon it, and fills you with a feeling of warmth and&W\n\r"
"&Whappyness at $n's passing,&W\n\r"
"\n\r"
"The Voice of the Gods can be Heard saying 'Welcome Home $n'\n\r"
"\n\r");
}
act( AT_PLAIN, message, victim, 0, 0, TO_ROOM );
}
else
act( AT_RED, "$n is DEAD!! R.I.P!",victim,NULL,NULL,TO_ROOM );
victim->died_in_room = NULL;
victim->died_in_room = victim->in_room;
return;
}
void do_char_ressurect( CHAR_DATA *ch )
{
if ( IS_IMMORTAL(ch) )
return;
if ( ch->perm_con <= 0 )
{
send_to_char("Ressurection Failed. You have no Constitution!\n\r",ch);
do_char_notressurect( ch );
return;
}
ch->perm_con--;
return;
}
void do_char_notressurect( CHAR_DATA *ch )
{
if( IS_IMMORTAL(ch) )
return;
/* New Ressurect Stuff --GW */
ch->pcdata->old_hp = ch->max_hit;
ch->pcdata->old_mana = ch->max_mana;
ch->pcdata->old_move = ch->max_move;
ch->pcdata->old_exp = ch->exp;
/* bug fix for the 'get 30k hp' bug */
ch->max_hit = ch->pcdata->old_hp;
ch->max_mana = ch->pcdata->old_mana;
/* Single or Dual class and Level > 2 */
if ( !IS_ADVANCED(ch) && ch->level > 2 )
{
lose_level(ch,ch->level-1,1);
ch->level--;
ch->pcdata->clssdropped = 1;
}
/* Dual Classed And
* Char First Level == 2 and char second level > 1
*/
else if ( !IS_ADVANCED(ch) && ch->level == 2 && ch->class2 > -1 && ch->level2 > 1 )
{
lose_level(ch,ch->level2-1,2);
ch->level2--;
ch->pcdata->clssdropped = 2;
}
/* Advanced and advlevel > 1 */
else if ( IS_ADVANCED(ch) && !IS_ADV_DUAL(ch) && ch->advlevel > 1 )
{
lose_level(ch,ch->advlevel-1,3);
ch->advlevel--;
ch->pcdata->clssdropped = 3;
}
/* Advanced Dual and advlevel2 > 1 */
else if ( IS_ADV_DUAL(ch) && ch->advlevel2 > 1 )
{
lose_level( ch, ch->advlevel2-1,4);
ch->advlevel2--;
ch->pcdata->clssdropped = 4;
}
else
{
send_to_char("Level loss Voided!\n\r",ch);
ch->pcdata->clssdropped = 0;
}
/* Added a Save here --GW */
save_char_obj(ch);
return;
}
void ego_update( CHAR_DATA *ch, CHAR_DATA *victim, bool gain )
{
int ego;
if ( IS_NPC( ch ) )
return;
if ( gain )
{
ego = ch->pcdata->ego;
if ( ego == 100 )
return;
/* for NPC, 1/2 of what lvl the npc is, or full level for PC kills */
if ( IS_NPC( victim ) )
ego += victim->level * 0.5;
else
ego += victim->level;
ch->pcdata->ego = ego;
/* Ego goes to 100 only. */
if ( ch->pcdata->ego > 100 )
ch->pcdata->ego = 100;
}
else
{
ego = ch->pcdata->ego;
/*for death, you lose 50 points */
ego -= 50;
if ( ego < 0 )
ego = 0;
ch->pcdata->ego = ego;
}
return;
}
char *get_ego_text( CHAR_DATA *ch )
{
int ego;
ego = ch->pcdata->ego;
if ( ego <= 10 )
return "is of teeny weenie loser type proportions";
if ( ego <= 20 )
return "is of tiny proportions";
if ( ego <= 30 )
return "is of small proportions";
if ( ego <= 40 )
return "is of humble proportions";
if ( ego <= 50 )
return "is of medium proportions";
if ( ego <= 60 )
return "is of bold proportions";
if ( ego <= 70 )
return "is of brave proportions";
if ( ego <= 80 )
return "is of GIGANTIC proportions";
if ( ego <= 90 )
return "is just plain EGOTISTICAL!";
if ( ego <= 100 )
return "is of Giganctic-Super-Google-Plex proportions";
else
return "is GODLY!";
}
/*
* Make Chars have Ghosts! --GW
*/
void create_ghost( CHAR_DATA *ch )
{
CHAR_DATA *ghost;
char buf[MSL];
AFFECT_DATA ghost_aff;
AFFECT_DATA *paf;
/* Create the ghost */
ghost=create_mobile( get_mob_index( 67, 1 ), find_zone(1));
/* Set the text */
sprintf(buf,"ghost %s",capitalize(ch->name));
ghost->name = STRALLOC(buf);
sprintf(buf,"The Ghost of %s",capitalize(ch->name));
ghost->short_descr = STRALLOC( buf );
sprintf(buf,"The Ghost of %s floats here..\n\r",ch->pcdata->title);
ghost->long_descr = STRALLOC(buf);
/* Hitpoints, mana, and Move */
ghost->max_hit = ch->max_hit;
ghost->max_mana = ch->max_mana;
ghost->max_move = ch->max_move;
/* Restore it .. */
ghost->hit = ghost->max_hit;
ghost->mana = ghost->max_mana;
ghost->move = ghost->max_move;
/* AC */
ghost->armor = ch->armor;
/* Hitroll */
ghost->hitroll = GET_HITROLL(ch);
/* Damage Roll */
ghost->damroll = GET_DAMROLL(ch);
/* Affects */
xSET_BITS( ghost->affected_by, ch->affected_by );
for( paf = ch->first_affect; paf; paf = paf->next )
{
ghost_aff.type = -1;
ghost_aff.duration = paf->duration;
ghost_aff.location = paf->location;
ghost_aff.modifier = paf->modifier;
xSET_BITS(ghost_aff.bitvector,paf->bitvector);
}
/* Level */
ghost->level = 100;
/* Numattacks */
ghost->numattacks = 5;
/* Make me a ghost! */
xSET_BIT(ghost->affected_by, AFF_GHOST);
/* Send it to the room */
char_to_room(ghost,ch->died_in_room);
act(AT_MAGIC,"As $N dies, a ghost slowly rises from the corpse...",ghost,NULL,ch,TO_ROOM);
return;
}
void ctf_death( CHAR_DATA *killer, CHAR_DATA *victim )
{
char buf[MSL];
extern int CTF_BLUE_FRAGS;
extern int CTF_RED_FRAGS;
extern int CTF_RED_CAPS;
extern int CTF_BLUE_CAPS;
OBJ_DATA *obj, *next_obj=NULL;
send_to_char("&RYou are Dead, Sorry....&W\n\r",victim);
stop_fighting(victim,TRUE);
char_from_room(victim);
sprintf(buf,"%s's Slaughtered by %s!",QUICKLINK(victim->name),QUICKLINK(killer->name));
ctf_channel(buf);
/* Score */
if ( (IS_NPC(killer) && victim->pcdata->team==TEAM_RED) || (!IS_NPC(killer) && killer->pcdata->team == TEAM_RED) )
CTF_RED_FRAGS++;
if ( (IS_NPC(killer) && victim->pcdata->team==TEAM_BLUE) || (!IS_NPC(killer) && killer->pcdata->team == TEAM_BLUE) )
CTF_BLUE_FRAGS++;
/* Show Score */
sprintf(buf,"Score: &RRed:&W %d Frags, %d Captures.",CTF_RED_FRAGS,CTF_RED_CAPS);
ctf_channel(buf);
sprintf(buf,"Score: &BBlue:&W %d Frags, %d Captures.",CTF_BLUE_FRAGS,CTF_BLUE_CAPS);
ctf_channel(buf);
if ( victim->pcdata->team == TEAM_RED )
char_to_room(victim,get_room_index(CTF_RED_BASE,1));
else
char_to_room(victim,get_room_index(CTF_BLUE_BASE,1));
victim->hit = victim->max_hit;
victim->mana = victim->max_mana;
victim->move = victim->max_move;
update_pos(victim);
do_look(victim,"auto");
send_to_char("You have been Restored. Back to the Fray!!\n\r",victim);
/* ctf flags stuff */
/* Red Flag Carrier */
if ( victim->pcdata->team == RED_FLAG_CARRIER )
flag_control( victim, TEAM_RED, 3 );
/* Blue Flag Carrier */
if ( victim->pcdata->team == BLUE_FLAG_CARRIER )
flag_control( victim, TEAM_BLUE, 3 );
for ( obj=victim->first_carrying; obj; obj = next_obj )
{
next_obj=obj->next_content;
if ( victim->pcdata->team == RED_FLAG_CARRIER && obj->pIndexData->vnum == CTF_RED_FLAG )
{
obj_from_char(obj);
obj_to_room(obj,get_room_index(CTF_RED_BASE,1));
break;
}
if ( victim->pcdata->team == BLUE_FLAG_CARRIER && obj->pIndexData->vnum == CTF_BLUE_FLAG )
{
obj_from_char(obj);
obj_to_room(obj,get_room_index(CTF_BLUE_BASE,1));
break;
}
}
return;
}