/**************************************************************************
* 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. *
* *
* Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, David *
* Love, Guilherme 'Willie' Arnold, and Mitchell Tse. *
* *
* In order to use any part of this Envy Diku Mud, you must comply with *
* the original Diku license in 'license.doc', the Merc license in *
* 'license.txt', as well as the Envy license in 'license.nvy'. *
* 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. *
***************************************************************************/
#define unix 1
#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"
/*
* Local functions.
*/
bool check_dodge args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
bool check_sidestep args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void check_killer args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
bool check_parry args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void dam_message args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dam,
int dt ) );
void death_cry args( ( CHAR_DATA *ch ) );
void death_xp_loss args( ( CHAR_DATA *victim ) );
void group_gain args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
int xp_compute args( ( CHAR_DATA *gch, CHAR_DATA *victim ) );
bool is_safe args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
bool is_bare_hand args( ( CHAR_DATA *ch ) );
bool is_wielding_poisoned args( ( CHAR_DATA *ch ) );
bool is_wielding_flaming args( ( CHAR_DATA *ch ) );
bool is_wielding_chaos args( ( CHAR_DATA *ch ) );
bool is_wielding_icy args( ( CHAR_DATA *ch ) );
void make_corpse args( ( CHAR_DATA *ch ) );
void one_hit args( ( CHAR_DATA *ch, CHAR_DATA *victim,
int dt ) );
void one_dual args( ( CHAR_DATA *ch, CHAR_DATA *victim,
int dt ) );
void one_triple args( ( CHAR_DATA *ch, CHAR_DATA *victim,
int dt ) );
void raw_kill args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void war_kill args( ( CHAR_DATA *ch ) );
void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void disarm args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void trip args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void item_damage args( ( CHAR_DATA *ch, int dam ) );
void do_image args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void do_flip args( ( CHAR_DATA *ch, char *argument ) );
OBJ_DATA *random_object args(( int level ));
/*
* Control the fights going on.
* Called periodically by update_handler.
* Slightly less efficient than Merc 2.2. Takes 10% of
* total CPU time.
*/
void violence_update( void )
{
CHAR_DATA *ch;
CHAR_DATA *victim;
CHAR_DATA *rch;
bool mobfighting;
int stun;
for ( ch = char_list; ch; ch = ch->next )
{
if ( !ch->in_room || ch->deleted )
continue;
for (stun = 0; stun < STUN_MAX; stun++)
{
if ( IS_STUNNED( ch, stun ) )
ch->stunned[stun]--;
}
if ( ( victim = ch->fighting ) )
{
if ( IS_AWAKE( ch ) && ch->in_room == victim->in_room )
multi_hit( ch, victim, TYPE_UNDEFINED );
else
stop_fighting( ch, FALSE );
continue;
}
if ( IS_AFFECTED( ch, AFF_BLIND )
|| ( IS_NPC( ch ) && ch->pIndexData->pShop ) )
continue;
/* Ok. So ch is not fighting anyone.
* Is there a fight going on?
*/
mobfighting = FALSE;
for ( rch = ch->in_room->people; rch; rch = rch->next_in_room )
{
if ( rch->deleted
|| !IS_AWAKE( rch )
|| !( victim = rch->fighting ) )
continue;
if ( !IS_NPC( ch )
&& ( !IS_NPC( rch ) || IS_AFFECTED( rch, AFF_CHARM ) )
&& is_same_group( ch, rch )
&& IS_NPC( victim ) )
break;
if ( IS_NPC( ch )
&& IS_NPC( rch )
&& !IS_NPC( victim ) )
{
mobfighting = TRUE;
break;
}
}
if ( !victim || !rch )
continue;
/*
* Now that someone is fighting, consider fighting another pc
* or not at all.
*/
if ( mobfighting )
{
CHAR_DATA *vch;
int number;
number = 0;
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
{
if ( can_see( ch, vch )
&& ( vch->level > 5 )
&& is_same_group( vch, victim )
&& number_range( 0, number ) == 0 )
{
victim = vch;
number++;
}
}
if ( ( rch->pIndexData != ch->pIndexData && number_bits( 3 ) != 0 )
|| ( IS_GOOD( ch ) && IS_GOOD( victim ) )
|| abs( victim->level - ch->level ) > 3 )
continue;
}
mprog_hitprcnt_trigger( ch, victim );
mprog_fight_trigger( ch, victim );
multi_hit( ch, victim, TYPE_UNDEFINED );
}
return;
}
/*
* Do one group of attacks.
*/
void multi_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
int chance;
int chance2;
if ( IS_NPC( ch ) )
{
mprog_hitprcnt_trigger( ch, victim );
mprog_fight_trigger( ch, victim );
}
if ( ( IS_AFFECTED2( ch, AFF_CONFUSED ) )
&& number_percent ( ) < 10 )
{
act(AT_YELLOW, "$n looks around confused at what's going on.", ch, NULL, NULL, TO_ROOM );
send_to_char( AT_YELLOW, "You stand confused.\n\r", ch );
return;
}
one_hit( ch, victim, dt );
if(IS_AFFECTED(ch, AFF_HASTE))
one_hit( ch, victim, dt );
if (IS_AFFECTED2( ch, AFF_RUSH ) )
one_hit( ch, victim, dt );
if ( ch->fighting != victim || dt == gsn_backstab )
return;
if ( !IS_NPC( ch )
&& ( ( is_class( ch, CLASS_MONK ) && ch->pcdata->learned[gsn_blackbelt] > 0 )
|| ( is_class( ch, CLASS_WEREWOLF ) && ch->pcdata->learned[gsn_dualclaw] > 0 )
|| ch->pcdata->learned[gsn_dual] > 0 ) )
{
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if(IS_AFFECTED(ch, AFF_HASTE))
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if ( IS_AFFECTED2( ch, AFF_RUSH ) )
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if ( ch->fighting != victim )
return;
}
if ( ( IS_NPC( ch ) ) && ( ch->level > 15 ) )
{
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if ( ch->fighting != victim )
return;
}
chance = IS_NPC( ch ) ? ch->level - 5
: ch->pcdata->learned[gsn_second_attack]/2;
if ( is_class( ch, CLASS_WEREWOLF ) )
chance2 = IS_NPC( ch ) ? ch->level / 2 - 5
: ch->pcdata->learned[gsn_dualclaw] / 2;
else if ( is_class( ch, CLASS_MONK ) && !get_eq_char( ch, WEAR_WIELD_2 ) )
chance2 = IS_NPC( ch ) ? ch->level / 2 - 5
: ch->pcdata->learned[gsn_blackbelt] / 2;
else
chance2 = IS_NPC( ch ) ? ch->level/2 - 5
: ch->pcdata->learned[gsn_dual]/2;
if ( number_percent( ) < chance )
{
one_hit( ch, victim, dt );
update_skpell( ch, gsn_second_attack );
if ( ch->fighting != victim )
return;
if ( number_percent( ) < chance2 )
{
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if ( ch->fighting != victim )
return;
}
}
chance = IS_NPC( ch ) ? ch->level
: ch->pcdata->learned[gsn_third_attack]/4;
if ( is_class( ch, CLASS_WEREWOLF ) )
chance2 = IS_NPC( ch ) ? ch->level / 2
: ch->pcdata->learned[gsn_dualclaw] / 4;
else if ( is_class( ch, CLASS_MONK ) && !get_eq_char( ch, WEAR_WIELD_2 ) )
chance2 = IS_NPC( ch ) ? ch->level / 2
: ch->pcdata->learned[gsn_blackbelt] / 4;
else
chance2 = IS_NPC( ch ) ? ch->level/2
:ch->pcdata->learned[gsn_dual]/4;
if ( number_percent( ) < chance )
{
one_hit( ch, victim, dt );
update_skpell( ch, gsn_third_attack );
if ( ch->fighting != victim )
return;
if ( number_percent( ) < chance2 )
{
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if ( ch->fighting != victim )
return;
}
}
chance = IS_NPC( ch ) ? ch->level/2
: ch->pcdata->learned[gsn_fourth_attack]/4;
if ( number_percent( ) < chance && ch->wait == 0 )
{
one_hit( ch, victim, dt );
update_skpell( ch, gsn_fourth_attack );
if ( ch->fighting != victim )
return;
}
chance = IS_NPC( ch ) ? ch->level/2
: ch->pcdata->learned[gsn_fifth_attack]/8;
if ( is_class( ch, CLASS_WEREWOLF ) )
chance2 = IS_NPC( ch ) ? ch->level / 6
: ch->pcdata->learned[gsn_dualclaw] / 8;
else if ( is_class( ch, CLASS_MONK ) && !get_eq_char( ch, WEAR_WIELD_2 ) )
chance2 = IS_NPC( ch ) ? ch->level / 6
: ch->pcdata->learned[gsn_blackbelt] / 8;
else
chance2 = IS_NPC( ch ) ? ch->level/6
: ch->pcdata->learned[gsn_dual]/8;
if ( number_percent( ) < chance && ch->wait == 0 )
{
one_hit( ch, victim, dt );
update_skpell( ch, gsn_fifth_attack );
if ( ch->fighting != victim )
return;
if ( number_percent( ) < chance2 )
{
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if ( ch->fighting != victim )
return;
}
}
chance = IS_NPC( ch ) ? ch->level/4
: ch->pcdata->learned[gsn_sixth_attack]/16;
if ( number_percent( ) < chance && ch->wait == 0 )
{
one_hit( ch, victim, dt );
update_skpell( ch, gsn_sixth_attack );
if ( ch->fighting != victim )
return;
}
chance = IS_NPC( ch ) ? ch->level/4
: ch->pcdata->learned[gsn_seventh_attack]/32;
if ( is_class( ch, CLASS_WEREWOLF ) )
chance2 = IS_NPC( ch ) ? ch->level / 4
: ch->pcdata->learned[gsn_dualclaw] / 32;
else if ( is_class( ch, CLASS_MONK ) && !get_eq_char( ch, WEAR_WIELD_2 ) )
chance2 = IS_NPC( ch ) ? ch->level / 4
: ch->pcdata->learned[gsn_blackbelt] / 22;
else
chance2 = IS_NPC( ch ) ? ch->level/4
: ch->pcdata->learned[gsn_dual]/32;
if ( number_percent( ) < chance && ch->wait == 0 )
{
one_hit( ch, victim, dt );
update_skpell( ch, gsn_seventh_attack );
if ( ch->fighting != victim )
return;
if ( number_percent( ) < chance2 )
{
one_dual( ch, victim, dt );
one_triple( ch, victim, dt );
if ( ch->fighting != victim )
return;
}
}
if ( IS_AFFECTED2(ch, AFF_BERSERK) )
{
one_hit( ch, victim, dt );
if (ch->fighting != victim )
return;
one_dual( ch, victim, dt );
if (ch->fighting != victim )
return;
one_triple( ch, victim, dt );
if (ch->fighting != victim )
return;
}
chance = IS_NPC( ch ) ? ch->level / 4
: 0;
chance2 = IS_NPC( ch ) ? ch->level / 8
: 0;
if ( number_percent( ) < chance )
one_hit( ch, victim, dt );
if ( number_percent( ) < chance2 )
one_dual( ch, victim, dt );
if ( number_percent( ) < chance2 )
one_triple( ch, victim, dt );
return;
}
/*
* Hit one guy once.
*/
void one_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
OBJ_DATA *wield;
char buf [ MAX_STRING_LENGTH ];
int victim_ac;
int thac0;
int thac0_00;
int thac0_97;
int dam;
int diceroll;
/*
* 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_STUNNED( ch, STUN_NON_MAGIC ) ||
IS_STUNNED( ch, STUN_TOTAL ) )
return;
/*
* Figure out the type of damage message.
*/
wield = get_eq_char( ch, WEAR_WIELD );
if ( dt == TYPE_UNDEFINED )
{
dt = TYPE_HIT;
if ( wield && wield->item_type == ITEM_WEAPON )
dt += wield->value[3];
else if ( is_class( ch, CLASS_WEREWOLF ) && !wield )
dt += 5;
else if ( is_class( ch, CLASS_MONK ) && !wield )
dt += 14;
}
/*
* Calculate to-hit-armor-class-0 versus armor.
*/
if ( IS_NPC( ch ) )
{
thac0_00 = 18;
thac0_97 = -24;
}
else
{
thac0_00 = class_table[prime_class(ch)].thac0_00;
thac0_97 = class_table[prime_class(ch)].thac0_97;
}
if (!IS_NPC(ch))
thac0 = interpolate( ch->level, thac0_00, thac0_97 )
- GET_HITROLL( ch );
else
thac0 = interpolate(ch->level, thac0_00, thac0_97 )
- (ch->level + ch->level/2);
if ( ( !IS_NPC( ch ) ) && ( ch->pcdata->learned[gsn_enhanced_hit] > 0 ) )
{
thac0 -= ch->pcdata->learned[gsn_enhanced_hit] / 5;
update_skpell( ch, gsn_enhanced_hit );
}
victim_ac = UMAX( -15, GET_AC( victim ) / 10 );
/*
if ( victim->level < L_APP && victim->class == CLASS_VAMPIRE )
if ( !IS_SET( victim->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 6 && time_info.hour < 18 )
{
victim_ac += victim->level * 2;
}
}
*/
if ( !can_see( ch, victim ) )
victim_ac -= 4;
/*
* The moment of excitement!
*/
while ( ( diceroll = number_bits( 5 ) ) >= 20 )
;
if ( diceroll == 0
|| ( diceroll != 19 && diceroll < thac0 - victim_ac ) )
{
/* Miss. */
damage( ch, victim, 0, dt );
tail_chain( );
return;
}
/*
* Hit.
* Calc damage.
*/
if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
{
if ( number_percent( ) < 50 )
{
if ( !IS_NPC(victim) )
spell_fireball ( skill_lookup("fireball"), 15, victim, ch );
else
spell_fireball ( skill_lookup("fireball"), 25, victim, ch );
}
}
if ( !victim || victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_AFFECTED( victim, AFF_ICESHIELD ) )
{
if ( ( number_percent( ) < 50 )
|| ( number_percent( ) < 17 ) )
{
if ( !IS_NPC(victim) )
spell_icestorm ( skill_lookup("icestorm"), 20, victim, ch );
else
spell_fireball ( skill_lookup("icestorm"), 40, victim, ch );
}
}
if ( !victim || victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) )
{
if ( ( number_percent( ) < 50 )
|| ( number_percent( ) < 17 ) )
{
if ( !IS_NPC(victim) )
spell_lightning_bolt ( skill_lookup("lightning bolt"), 15, victim, ch );
else
spell_lightning_bolt ( skill_lookup("lightning bolt"), 35, victim, ch );
}
}
if ( !victim || victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_AFFECTED( victim, AFF_CHAOS ) )
{
if ( number_percent( ) < 50 )
{
if ( !IS_NPC(victim) )
spell_energy_drain ( skill_lookup("energy drain"), 30, victim, ch );
else
spell_energy_drain ( skill_lookup("energy drain"), 40, victim, ch );
}
}
if ( !victim || victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_AFFECTED( victim, AFF_VIBRATING ) )
{
if ( ( number_percent( ) < 50 )
|| ( number_percent( ) < 17 ) )
spell_psionic_blast ( skill_lookup("psionic blast"), 25, victim, ch );
}
if ( !victim || victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_AFFECTED2( victim, AFF_BLADE ) )
{
if ( number_percent( ) < 40 )
spell_holy_fires( skill_lookup("holy fires"), 45, victim, ch );
}
if ( !victim || victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_AFFECTED2( victim, AFF_FIELD ) )
{
if ( number_percent( ) < 10 )
spell_death_field( skill_lookup("death field"),
victim->level, victim, ch );
}
if ( !victim || victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_NPC( ch ) )
{
dam = number_range( ch->level / 3, ch->level * 3 / 2 );
if ( wield )
dam += dam / 3;
}
else
{
if ( wield )
dam = number_range( wield->value[1], wield->value[2] );
else if ( (is_class( ch, CLASS_WEREWOLF )
|| is_class( ch, CLASS_MONK ))
&& !wield )
dam = UMAX( number_fuzzy( ch->level / 2 + ch->level / 15 ),
number_fuzzy( 5 ) );
else
dam = number_range( 1, 4 );
if ( wield && dam > 1000 && !IS_IMMORTAL(ch) )
{
sprintf( buf, "One_hit dam range > 1000 from %d to %d",
wield->value[1], wield->value[2] );
bug( buf, 0 );
if ( wield->name )
bug( wield->name, 0 );
}
}
/*
* Bonuses.
*/
dam += GET_DAMROLL( ch );
if ( wield && IS_SET( wield->extra_flags, ITEM_POISONED ) )
dam += dam / 8;
if (
(wield && IS_SET( wield->extra_flags, ITEM_FLAME ) )
|| (!wield && is_affected( ch, gsn_flamehand ) )
)
dam += dam / 8;
if (
(wield && IS_SET( wield->extra_flags, ITEM_CHAOS ) )
|| (!wield && is_affected( ch, gsn_chaoshand ) )
)
dam += dam / 4;
if (
(wield && IS_SET( wield->extra_flags, ITEM_ICY ) )
|| (!wield && is_affected( ch, gsn_frosthand ) )
)
dam += dam / 8;
if ( is_class( ch, CLASS_WEREWOLF ) && !wield )
dam += dam / 8;
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_damage] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_damage] / 150;
update_skpell( ch, gsn_enhanced_damage );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_claw] > 0
&& !wield )
{
dam += dam / 4 * ch->pcdata->learned[gsn_enhanced_claw] / 150;
update_skpell( ch, gsn_enhanced_claw );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_two] > 0 )
{
dam += dam / 4 * ch->pcdata->learned[gsn_enhanced_two] / 150;
update_skpell( ch, gsn_enhanced_two );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_three] > 0 )
{
dam += dam / 4 * ch->pcdata->learned[gsn_enhanced_three] / 150;
update_skpell( ch, gsn_enhanced_three );
}
if ( !IS_AWAKE( victim ) )
dam *= 2;
if ( dt == gsn_backstab )
{
if (ch->clan == 4)
dam *= number_range ( 3, 8 );
else
dam *= 2 + UMIN( ( ch->level / 8) , 4 );
}
if ( dam <= 0 )
dam = 1;
damage( ch, victim, dam, dt );
tail_chain( );
return;
}
void one_dual( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
OBJ_DATA *wield;
char buf [ MAX_STRING_LENGTH ];
int victim_ac;
int thac0;
int thac0_00;
int thac0_97;
int dam;
int diceroll;
/*
* Can't beat a dead char!
* Guard against weird room-leavings.
*/
if ( !(get_eq_char( ch, WEAR_WIELD_2 ))
&& !is_class( ch, CLASS_WEREWOLF )
&& !is_class( ch, CLASS_MONK ) )
return;
if ( is_class( ch, CLASS_WEREWOLF )
&& ( get_eq_char( ch, WEAR_SHIELD )
|| get_eq_char( ch, WEAR_HOLD ) ) )
return;
if ( is_class( ch, CLASS_MONK )
&& ( get_eq_char( ch, WEAR_SHIELD )
|| get_eq_char( ch, WEAR_HOLD ) ) )
return;
if ( ( is_class( ch, CLASS_MONK ) && ch->pcdata->learned[gsn_blackbelt] == 0 )
&& ( is_class( ch, CLASS_WEREWOLF ) && ch->pcdata->learned[gsn_dualclaw] == 0 )
&& !get_eq_char( ch, WEAR_WIELD_2 ) )
return;
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_STUNNED( ch, STUN_NON_MAGIC ) ||
IS_STUNNED( ch, STUN_TOTAL ) )
return;
/*
* Figure out the type of damage message.
*/
wield = get_eq_char( ch, WEAR_WIELD_2 );
if ( dt == TYPE_UNDEFINED )
{
dt = TYPE_HIT;
if ( wield && wield->item_type == ITEM_WEAPON )
dt += wield->value[3];
else if ( is_class( ch, CLASS_WEREWOLF ) && !wield )
dt += 5;
else if ( is_class( ch, CLASS_MONK ) && !wield )
dt += 15;
}
/*
* Calculate to-hit-armor-class-0 versus armor.
*/
if ( IS_NPC( ch ) )
{
thac0_00 = 20;
thac0_97 = -20;
}
else
{
thac0_00 = class_table[prime_class(ch)].thac0_00;
thac0_97 = class_table[prime_class(ch)].thac0_97;
}
thac0 = interpolate( ch->level, thac0_00, thac0_97 )
- GET_HITROLL( ch );
victim_ac = UMAX( -15, GET_AC( victim ) / 10 );
/*
if ( victim->level < L_APP && victim->class == CLASS_VAMPIRE )
if ( !IS_SET( victim->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 6 && time_info.hour < 18 )
{
victim_ac += victim->level * 2;
}
}
*/
if ( !can_see( ch, victim ) )
victim_ac -= 4;
/*
* The moment of excitement!
*/
while ( ( diceroll = number_bits( 5 ) ) >= 20 )
;
if ( diceroll == 0
|| ( diceroll != 19 && diceroll < thac0 - victim_ac ) )
{
/* Miss. */
damage( ch, victim, 0, dt );
tail_chain( );
return;
}
update_skpell( ch, gsn_dual );
/*
* Hit.
* Calc damage.
*/
/* if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
{
if ( number_percent( ) < 50 )
spell_fireball ( skill_lookup("fireball"), 5, victim, ch );
}
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) )
{
if ( number_percent( ) < 50 )
spell_lightning_bolt ( skill_lookup("lightning bolt"), 15, victim, ch );
}
if ( IS_AFFECTED( victim, AFF_CHAOS ) )
{
if ( number_percent( ) < 50 )
spell_energy_drain ( skill_lookup("energy drain"), 25, victim, ch );
}
if ( IS_AFFECTED( victim, AFF_VIBRATING ) )
{
if ( number_percent( ) < 50 )
spell_psionic_blast ( skill_lookup("psionic blast"), 25, victim, ch );
}*/
if ( IS_NPC( ch ) )
{
dam = number_range( ch->level / 3, ch->level );
if ( wield )
dam += dam / 4;
}
else
{
if ( wield )
dam = number_range( wield->value[1], wield->value[2] );
else if ( (is_class( ch, CLASS_WEREWOLF )
|| is_class( ch, CLASS_MONK ))
&& !wield )
dam = UMAX( number_fuzzy( ch->level / 2 + ch->level / 15 ),
number_fuzzy( 5 ) );
else
dam = number_range( 1, 4 );
if ( wield && dam > 1000 )
{
sprintf( buf, "One_hit dam range > 1000 from %d to %d",
wield->value[1], wield->value[2] );
bug( buf, 0 );
}
}
/*
* Bonuses.
*/
dam += GET_DAMROLL( ch );
if ( wield && IS_SET( wield->extra_flags, ITEM_POISONED ) )
dam += dam / 4;
if (
(wield && IS_SET( wield->extra_flags, ITEM_FLAME ) )
|| (!wield && is_affected( ch, gsn_flamehand ) )
)
dam += dam / 8;
if (
(wield && IS_SET( wield->extra_flags, ITEM_CHAOS ) )
|| (!wield && is_affected( ch, gsn_chaoshand ) )
)
dam += dam / 8;
if (
(wield && IS_SET( wield->extra_flags, ITEM_ICY ) )
|| (!wield && is_affected( ch, gsn_frosthand ) )
)
dam += dam / 4;
if ( is_class( ch, CLASS_WEREWOLF ) && !wield )
{
dam += dam / 4;
update_skpell( ch, gsn_dualclaw );
}
if ( is_class( ch, CLASS_MONK ) && !wield )
update_skpell( ch, gsn_blackbelt );
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_damage] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_damage] / 150;
update_skpell( ch, gsn_enhanced_damage );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_claw] > 0
&& !wield )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_claw] / 150;
update_skpell( ch, gsn_enhanced_claw );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_two] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_two] / 150;
update_skpell( ch, gsn_enhanced_two );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_three] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_three] / 150;
update_skpell( ch, gsn_enhanced_three );
}
if ( !IS_AWAKE( victim ) )
dam *= 2;
if ( dt == gsn_backstab )
dam *= 2 + UMIN( ( ch->level / 8) , 4 );
if ( dam <= 0 )
dam = 1;
damage( ch, victim, dam, dt );
tail_chain( );
return;
}
void one_triple( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
OBJ_DATA *wield;
char buf [ MAX_STRING_LENGTH ];
int victim_ac;
int thac0;
int thac0_00;
int thac0_97;
int dam;
int diceroll;
/*
* Can't beat a dead char!
* Guard against weird room-leavings.
*/
if ( !(get_eq_char( ch, WEAR_WIELD_3 )))
return;
if (( get_eq_char( ch, WEAR_SHIELD )
|| get_eq_char( ch, WEAR_HOLD ) ) )
return;
if ( ( get_eq_char( ch, WEAR_SHIELD )
|| get_eq_char( ch, WEAR_HOLD ) ) )
return;
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_STUNNED( ch, STUN_NON_MAGIC ) ||
IS_STUNNED( ch, STUN_TOTAL ) )
return;
/*
* Figure out the type of damage message.
*/
wield = get_eq_char( ch, WEAR_WIELD_3 );
if ( dt == TYPE_UNDEFINED )
{
dt = TYPE_HIT;
if ( wield && wield->item_type == ITEM_WEAPON )
dt += wield->value[3];
}
/*
* Calculate to-hit-armor-class-0 versus armor.
*/
if ( IS_NPC( ch ) )
{
thac0_00 = 20;
thac0_97 = -20;
}
else
{
thac0_00 = class_table[prime_class(ch)].thac0_00;
thac0_97 = class_table[prime_class(ch)].thac0_97;
}
thac0 = interpolate( ch->level, thac0_00, thac0_97 )
- GET_HITROLL( ch );
victim_ac = UMAX( -15, GET_AC( victim ) / 10 );
if ( !can_see( ch, victim ) )
victim_ac -= 4;
/*
* The moment of excitement!
*/
while ( ( diceroll = number_bits( 5 ) ) >= 20 )
;
if ( diceroll == 0
|| ( diceroll != 19 && diceroll < thac0 - victim_ac ) )
{
/* Miss. */
damage( ch, victim, 0, dt );
tail_chain( );
return;
}
/*
* Hit.
* Calc damage.
*/
/* if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
{
if ( number_percent( ) < 50 )
spell_fireball ( skill_lookup("fireball"), 5, victim, ch );
}
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) )
{
if ( number_percent( ) < 50 )
spell_lightning_bolt ( skill_lookup("lightning bolt"), 15, victim, ch );
}
if ( IS_AFFECTED( victim, AFF_CHAOS ) )
{
if ( number_percent( ) < 50 )
spell_energy_drain ( skill_lookup("energy drain"), 25, victim, ch );
}
if ( IS_AFFECTED( victim, AFF_VIBRATING ) )
{
if ( number_percent( ) < 50 )
spell_psionic_blast ( skill_lookup("psionic blast"), 25, victim, ch );
}*/
if ( IS_NPC( ch ) )
{
dam = number_range( ch->level / 3, ch->level );
if ( wield )
dam += dam / 4;
}
else
{
if ( wield )
dam = number_range( wield->value[1], wield->value[2] );
else
dam = number_range( 1, 4 );
if ( wield && dam > 5000 )
{
sprintf( buf, "One_hit dam range > 1000 from %d to %d",
wield->value[1], wield->value[2] );
bug( buf, 0 );
}
}
/*
* Bonuses.
*/
dam += GET_DAMROLL( ch );
if ( wield && IS_SET( wield->extra_flags, ITEM_POISONED ) )
dam += dam / 4;
if (
(wield && IS_SET( wield->extra_flags, ITEM_FLAME ) )
|| (!wield && is_affected( ch, gsn_flamehand ) )
)
dam += dam / 8;
if (
(wield && IS_SET( wield->extra_flags, ITEM_CHAOS ) )
|| (!wield && is_affected( ch, gsn_chaoshand ) )
)
dam += dam / 8;
if ( wield && IS_SET( wield->extra_flags, ITEM_ICY ) )
dam += dam / 4;
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_damage] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_damage] / 150;
update_skpell( ch, gsn_enhanced_damage );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_two] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_two] / 150;
update_skpell( ch, gsn_enhanced_two );
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_enhanced_three] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_enhanced_three] / 150;
update_skpell( ch, gsn_enhanced_three );
}
if ( !IS_AWAKE( victim ) )
dam *= 2;
if ( dt == gsn_backstab )
dam *= 2 + UMIN( ( ch->level / 8) , 4 );
if ( dam <= 0 )
dam = 1;
damage( ch, victim, dam, dt );
tail_chain( );
return;
}
/*
* Inflict damage from a hit.
*/
void damage( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt )
{
DESCRIPTOR_DATA *d;
bool warkilled = FALSE;
if ( victim->position == POS_DEAD )
return;
if(!IS_NPC(ch) && !IS_NPC(victim))
{
if (!(ch == victim) )
{
ch->combat_timer = 90;
victim->combat_timer = 90;
}
}
/*
* Stop up any residual loopholes.
*/
if ( dam > 3500 )
{
char buf [ MAX_STRING_LENGTH ];
if ( dt != 91 && ch->level <= LEVEL_HERO
&& dt != 40 )
{
if ( IS_NPC( ch ) && ch->desc && ch->desc->original )
sprintf( buf,
"Damage: %d from %s by %s: > 3500 points with %d dt!",
dam, ch->name, ch->desc->original->name, dt );
else
sprintf( buf,
"Damage: %d from %s: > 3500 points with %d dt!",
dam, ch->name, dt );
bug( buf, 0 );
}
}
if ( victim != ch )
{
/*
* Certain attacks are forbidden.
* Most other attacks are returned.
*/
if ( is_safe( ch, victim ) )
return;
check_killer( ch, victim );
if ( victim->position > POS_STUNNED )
{
if ( !victim->fighting )
set_fighting( victim, ch );
victim->position = POS_FIGHTING;
}
if ( victim->position > POS_STUNNED )
{
if ( !ch->fighting )
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
&& victim->master->in_room == ch->in_room
&& number_bits( 3 ) == 0 )
{
stop_fighting( ch, FALSE );
set_fighting( ch, victim->master );
return;
}
}
/*
* More charm stuff.
*/
if ( victim->master == ch )
stop_follower( victim );
/*
* Inviso attacks ... not.
*/
if ( IS_AFFECTED( ch, AFF_INVISIBLE ) )
{
affect_strip( ch, gsn_invis );
affect_strip( ch, gsn_mass_invis );
REMOVE_BIT( ch->affected_by, AFF_INVISIBLE );
act(AT_GREY, "$n fades into existence.", ch, NULL, NULL, TO_ROOM );
}
if (IS_AFFECTED2( ch, AFF_PHASED ) )
{
affect_strip ( ch, skill_lookup("phase shift") );
affect_strip ( ch, skill_lookup("mist form") );
REMOVE_BIT( ch->affected_by2, AFF_PHASED );
act(AT_GREY, "$n returns from an alternate plane.", ch, NULL, NULL, TO_ROOM );
}
/*
* Damage modifiers.
*/
if ( ch->race == RACE_OGRE )
dam -= dam / 20;
/*
if ( ch->level < L_APP && ch->class == CLASS_VAMPIRE )
if ( !IS_SET( ch->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 6 && time_info.hour < 18 )
{
send_to_char( AT_RED,
"The sunlight has weakened your attack.\n\r", ch );
dam -= dam / 2;
}
}
if ( victim->level < L_APP && victim->class == CLASS_VAMPIRE )
if ( !IS_SET( victim->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 6 && time_info.hour < 18 )
{
send_to_char( AT_RED,
"The sunlight has weakened your defence.\n\r", victim );
dam += dam / 2;
}
}
if ( ch->class == CLASS_VAMPIRE )
if ( !IS_SET( ch->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 23 || time_info.hour < 1 )
{
dam *= 2;
}
}
if ( victim->class == CLASS_VAMPIRE )
if ( !IS_SET( victim->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 23 || time_info.hour < 1 )
{
dam /= 2;
}
}
*/
/*
* Check for disarm, trip, parry, and dodge.
*/
if ( dt >= TYPE_HIT || dt == gsn_feed
|| dt == gsn_jab_punch || dt == gsn_kidney_punch
|| dt == gsn_cross_punch || dt == gsn_roundhouse_punch
|| dt == gsn_uppercut_punch || dt == gsn_punch
|| dt == gsn_flykick || dt == gsn_high_kick
|| dt == gsn_jump_kick || dt == gsn_spin_kick
|| dt == gsn_kick
)
{
int leveldiff = ch->level - victim->level;
if ( IS_NPC( ch ) && number_percent( )
< ( leveldiff < -5 ? ch->level / 2 : UMAX( 10, leveldiff ) )
&& dam == 0 && number_bits(4) == 0)
disarm( ch, victim );
if ( IS_NPC( ch ) && number_percent( )
< ( leveldiff < -5 ? ch->level / 2 : UMAX( 20, leveldiff ) )
&& dam == 0 && number_bits(4) == 0)
trip( ch, victim );
if ( check_parry( ch, victim ) && dam > 0 )
return;
if ( check_dodge( ch, victim ) && dam > 0 )
return;
if ( check_sidestep( ch, victim ) && dam > 0 )
return;
}
if ( !IS_NPC( ch )
&& ( dt == 1014 || dt == 1015 /* FIST & CLAW */
|| ( dt == 1005 /* DAMAGE - Hann */
&& is_class( ch, CLASS_WEREWOLF )
&& is_class( ch, CLASS_MONK )
&& is_bare_hand( ch ) ) )
&& ch->pcdata->learned[gsn_anatomyknow] > 0
&& number_percent( ) <= ch->pcdata->learned[gsn_anatomyknow] / 9 )
{
update_skpell( ch, gsn_anatomyknow );
send_to_char( AT_RED, "You hit a pressure point!\n\r", ch );
act( AT_RED, "$n hit one of $N's pressure points!",
ch, NULL, victim, TO_NOTVICT );
act( AT_RED, "$n hit you with a precise shot.",
ch, NULL, victim, TO_VICT );
if ( number_percent( ) < 2 )
{
victim->hit = 1;
}
else if ( number_percent( ) < 10 )
{
STUN_CHAR( victim, 2, STUN_TOTAL );
victim->position = POS_STUNNED;
dam *= 4;
}
else
dam += 500;
}
if ( IS_AFFECTED( victim, AFF_SANCTUARY ) )
dam /= 2;
if ( IS_AFFECTED2( victim, AFF_GOLDEN ) )
dam /= 4;
if ( IS_AFFECTED2( victim, AFF_DANCING ) )
dam += dam/2;
if ( IS_AFFECTED( victim, AFF_FIRESHIELD )
&& !( dt == gsn_backstab && chance( number_range( 5, 10 ) ) ) )
dam -= dam / 8;
if ( IS_AFFECTED( victim, AFF_ICESHIELD )
&& !( dt == gsn_backstab && chance( number_range( 5, 10 ) ) ) )
dam -= dam / 8;
if ( IS_AFFECTED( victim, AFF_CHAOS )
&& !( dt == gsn_backstab && chance( number_range( 5, 10 ) ) ) )
dam -= dam / 4;
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD )
&& !( dt == gsn_backstab && chance( number_range( 5, 10 ) ) ) )
dam -= dam / 4;
if ( IS_AFFECTED( victim, AFF_VIBRATING )
&& !( dt == gsn_backstab && chance( number_range( 5, 10 ) ) ) )
dam -= dam / 4;
if ( IS_AFFECTED2( victim, AFF_INERTIAL ) )
dam -= dam / 8;
if ( IS_SET( victim->act, UNDEAD_TYPE( victim ) ) )
dam -= dam / 8;
if ( IS_AFFECTED2( victim, AFF_BLADE )
&& !( dt == gsn_backstab && chance( number_range( 5, 10 ) ) ) )
dam -= dam / 4;
if ( IS_AFFECTED2( victim, AFF_FIELD )
&& !( dt == gsn_backstab && chance( number_range( 5, 10 ) ) ) )
dam -= dam / 4;
if ( IS_AFFECTED( victim, AFF_PROTECT )
&& IS_EVIL( ch ) )
dam -= dam / 4;
if ( IS_AFFECTED2( victim, AFF_PROTECTION_GOOD )
&& IS_EVIL( ch ) )
dam -= dam / 4;
if ( dam < 0 )
dam = 0;
}
/* We moved dam_message out of the victim != ch if above
* so self damage would show. Other valid type_undefined
* damage is ok to avoid like mortally wounded damage - Kahn
*/
if ( ( !IS_NPC(ch) ) && ( !IS_NPC(victim) ) )
dam -= dam/4;
if ( dt != TYPE_UNDEFINED )
dam_message( ch, victim, dam, dt );
/*
* Hurt the victim.
* Inform the victim of his new state.
*/
if ( !IS_NPC(ch) && prime_class( ch ) == CLASS_WARRIOR )
dam += dam/2;
if ( ( !IS_NPC(ch) ) && (ch->race == RACE_OGRE ) )
dam += dam/10;
if (!IS_NPC(ch) && !IS_NPC(victim))
dam /= number_range(2, 4);
if ( dam > 25 && number_range( 0, 100 ) <= 15 )
item_damage(victim, dam);
victim->hit -= dam;
if ( ( ( !IS_NPC( victim ) /* so imms only die by */
&& IS_NPC( ch ) /* the hands of a PC */
&& victim->level >= LEVEL_IMMORTAL )
||
( !IS_NPC( victim ) /* so imms don,t die */
&& victim->level >= LEVEL_IMMORTAL /* by poison type dmg */
&& ch == victim ) ) /* since an imm == pc */
&& victim->hit < 1 )
victim->hit = 1;
if ( dam > 0 && dt > TYPE_HIT
&& ( ( is_wielding_poisoned( ch )
&& !saves_spell( ch->level, victim ) )
|| ( is_class( ch, CLASS_WEREWOLF ) && is_bare_hand( ch ) ) )
&& victim->race != RACE_GHOUL )
{
AFFECT_DATA af;
af.type = gsn_poison;
af.duration = 1;
af.location = APPLY_STR;
af.modifier = -2;
af.bitvector = AFF_POISON;
affect_join( victim, &af );
}
if ( dam > 0 && dt > TYPE_HIT
&& is_wielding_flaming( ch )
&& number_percent( ) < 10 )
spell_fireball ( skill_lookup("fireball"), 20, ch, victim );
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( dam > 0 && ( dt == 1014
|| dt == 1015
|| ( dt == 1005
&& is_class( ch, CLASS_WEREWOLF )
&& is_class( ch, CLASS_MONK )
&& is_bare_hand( ch ) ) )
&& is_affected( ch, gsn_flamehand )
&& number_percent( ) < 33 )
spell_burning_hands( skill_lookup("burning hands"),
ch->level, ch, victim );
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( dam > 0 && dt > TYPE_HIT
&& is_wielding_icy( ch )
&& number_percent( ) < 20 )
spell_icestorm ( skill_lookup("icestorm"), 30, ch, victim );
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( dam > 0 && ( dt == 1014
|| dt == 1015
|| ( dt == 1005
&& is_class( ch, CLASS_WEREWOLF )
&& is_class( ch, CLASS_MONK )
&& is_bare_hand( ch ) ) )
&& is_affected( ch, gsn_frosthand )
&& number_percent( ) < 20 )
spell_chill_touch( skill_lookup("chill touch"), ch->level * 3,
ch, victim );
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( dam > 0 && dt > TYPE_HIT
&& is_wielding_chaos( ch )
&& number_percent( ) < 20 )
spell_energy_drain ( skill_lookup("energy drain"), 45, ch, victim );
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( dam > 0 && ( dt == 1014
|| dt == 1015
|| ( dt == 1005
&& is_class( ch, CLASS_WEREWOLF )
&& is_class( ch, CLASS_MONK )
&& is_bare_hand( ch ) ) )
&& is_affected( ch, gsn_chaoshand )
&& number_percent( ) < 10 )
spell_energy_drain( skill_lookup("energy drain"),
ch->level * 1.5, ch, victim );
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;
if ( IS_SET( ch->act, UNDEAD_TYPE( ch ) )
&& !saves_spell(ch->level, victim )
&& !is_class( victim, CLASS_NECROMANCER )
&& victim->race != RACE_GHOUL )
{
AFFECT_DATA af;
af.type = gsn_poison;
af.duration = 2;
af.location = APPLY_CON;
af.modifier = -1;
af.bitvector = AFF_POISON;
affect_join( victim, &af );
}
update_pos( victim );
switch( victim->position )
{
case POS_MORTAL:
send_to_char(AT_RED,
"You are mortally wounded, and will die soon, if not aided.\n\r",
victim );
act(AT_RED, "$n is mortally wounded, and will die soon, if not aided.",
victim, NULL, NULL, TO_ROOM );
break;
case POS_INCAP:
send_to_char(AT_RED,
"You are incapacitated and will slowly die, if not aided.\n\r",
victim );
act(AT_RED, "$n is incapacitated and will slowly die, if not aided.",
victim, NULL, NULL, TO_ROOM );
break;
case POS_STUNNED:
send_to_char(AT_WHITE,"You are stunned, but will probably recover.\n\r",
victim );
act(AT_WHITE, "$n is stunned, but will probably recover.",
victim, NULL, NULL, TO_ROOM );
break;
case POS_DEAD:
send_to_char(AT_BLOOD, "You have been KILLED!!\n\r\n\r", victim );
act(AT_BLOOD, "$n is DEAD!!", victim, NULL, NULL, TO_ROOM );
break;
default:
if ( dam > MAX_HIT(victim) / 4 )
send_to_char(AT_RED, "That really did HURT!\n\r", victim );
if ( victim->hit < MAX_HIT(victim) / 4 )
send_to_char(AT_RED, "You sure are BLEEDING!\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 )
{
if ( !IS_ARENA(ch) && !IS_SET( victim->act2, PLR_WAR ))
{
group_gain( ch, victim );
if(((ch->guild != NULL) ? ch->guild->type & GUILD_CHAOS : 0)
&& ch->guild == victim->guild
&& victim->guild_rank > ch->guild_rank)
{
int temp;
temp = ch->guild_rank;
ch->guild_rank = victim->guild_rank;
victim->guild_rank = temp;
}
if ( ( !IS_NPC(ch) ) && ( !IS_NPC(victim) ) )
{
CLAN_DATA *pClan;
CLAN_DATA *Cland;
if ( ch->clan != victim->clan )
{
if ( (pClan = get_clan_index(ch->clan)) != NULL )
pClan->pkills++;
if ( (Cland = get_clan_index(victim->clan)) != NULL )
Cland->pdeaths++;
}
/* REMOVE_BIT(victim->act, PLR_THIEF);*/
}
if ( ( !IS_NPC(ch) ) && ( IS_NPC(victim) ) )
{
CLAN_DATA *pClan;
if ( (pClan=get_clan_index(ch->clan)) != NULL )
pClan->mkills++;
}
if ( ( IS_NPC(ch) ) && (!IS_NPC(victim)) )
{
CLAN_DATA *pClan;
if ( (pClan=get_clan_index(victim->clan)) != NULL )
pClan->mdeaths++;
}
if ( !IS_NPC( victim ) )
{
if (!IS_NPC(ch) && ch != victim)
{
ch->pkills++;
victim->pkilled++;
}
/*
* Dying penalty:
* 1/2 way back to previous level.
*/
if ( victim->level < LEVEL_HERO
|| ( victim->level >= LEVEL_HERO && IS_NPC( ch ) ) )
/* death_xp_loss( victim ); */
sprintf( log_buf, "%s killed by %s at %d.", victim->name,
ch->name, victim->in_room->vnum );
log_string( log_buf, CHANNEL_LOG, -1 );
wiznet(log_buf,NULL,NULL,WIZ_DEATHS,0,0);
if ( !IS_NPC( ch )
&& IS_SET( victim->act, PLR_THIEF )
&& ch->guild
&& !strcmp( ch->guild->name, "MERCENARY" ) )
{
REMOVE_BIT( victim->act, PLR_THIEF );
info( "%s the puny thief gets destroyed by the &rMERCENARY&C %s!",
(int)victim->name, (int)ch->name );
}
else if ( !IS_NPC( ch )
&& IS_SET( ch->act, PLR_THIEF )
&& victim->guild
&& !strcmp( victim->guild->name, "MERCENARY" ) )
{
info( "%s, the sly thief, has killed the &rMERCENARY&C %s.",
(int)ch->name, (int)victim->name );
if ( ch != victim )
{
ch->pkills++;
victim->pkilled++;
}
}
else
{
info( "%s gets slaughtered by %s!", (int)victim->name,
(int)(IS_NPC(ch) ? ch->short_descr : ch->name) );
}
save_clans();
}
}
else if(war.iswar == TRUE && IS_SET(victim->act2, PLR_WAR))
{
char buf[MAX_STRING_LENGTH];
warkilled = TRUE;
sprintf(buf, "&C%s &chas become a casualty of war.", victim->name );
info(buf, 0, 0 );
ch->warpts = ch->warpts + 1;
send_to_char(C_DEFAULT, "You have been awarded 1 war point for your kill.\n\r", ch);
ch->warkills = ch->warkills + 1;
victim->wardeaths = victim->wardeaths + 1;
if(IS_SET(victim->act2, TEAM_RED))
war.team_red--;
if(IS_SET(victim->act2, TEAM_BLUE))
war.team_blue--;
war.inwar--;
if (!IS_NPC( victim ))
war_kill( victim );
if (war.wartype == 1 && war.inwar == 1)
{
sprintf( buf, "&C%s &Rhas survived iron man war!", ch->name );
info( buf, 0, 0 );
ch->warpts = ch->warpts + 100;
send_to_char(C_DEFAULT, "You have been awarded 100 war points for your victory.\n\r", ch);
war.wartype = 0;
war.max_level = 0;
war.max_level = 0;
war.inwar = 0;
war.count = 0;
war.timeleft = 0;
war.iswar = FALSE;
REMOVE_BIT(ch->act2, PLR_WAR);
char_from_room(ch);
char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE));
}
else if(war.team_red == 0 && war.wartype != 1)
{
sprintf( buf, "&CThe &BBLUE TEAM &chas won the war!" );
info( buf, 0, 0 );
ch->warpts = ch->warpts + 20;
send_to_char(C_DEFAULT, "You have been awarded 20 war points for the winning kill.\n\r", ch);
war.wartype = 0;
war.max_level = 0;
war.max_level = 0;
war.inwar = 0;
war.count = 0;
war.timeleft = 0;
war.iswar = FALSE;
REMOVE_BIT(ch->act2, PLR_WAR);
REMOVE_BIT(ch->act2, TEAM_BLUE);
char_from_room(ch);
char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE));
for (d = descriptor_list; d != NULL; d = d->next)
{
if (!IS_NPC(d->character))
{
if (IS_SET(d->character->act2, PLR_WAR))
REMOVE_BIT(d->character->act2, PLR_WAR);
if(IS_SET(d->character->act2, TEAM_RED))
REMOVE_BIT(d->character->act2, TEAM_RED);
if(IS_SET(d->character->act2, TEAM_BLUE))
{
ch->warpts = ch->warpts + 10;
send_to_char(C_DEFAULT, "You have been awarded 10 war points for your victory.\n\r", ch);
REMOVE_BIT(d->character->act2, TEAM_BLUE);
}
}
}
}
else if(war.team_blue == 0 && war.wartype != 1 )
{
sprintf( buf, "&CThe &RRED TEAM &chas won the war!" );
info( buf, 0, 0 );
ch->warpts = ch->warpts + 20;
send_to_char(C_DEFAULT, "You have been awarded 20 war points for the winning kill.\n\r", ch);
war.wartype = 0;
war.max_level = 0;
war.max_level = 0;
war.inwar = 0;
war.count = 0;
war.timeleft = 0;
war.iswar = FALSE;
REMOVE_BIT(ch->act2, PLR_WAR);
if(IS_SET(ch->act2, TEAM_RED))
REMOVE_BIT(ch->act2, TEAM_RED);
char_from_room(ch);
char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE));
for (d = descriptor_list; d != NULL; d = d->next)
{
if (!IS_NPC(d->character))
{
if (IS_SET(d->character->act2, PLR_WAR))
REMOVE_BIT(d->character->act2, PLR_WAR);
if(IS_SET(d->character->act2, TEAM_RED))
{
ch->warpts = ch->warpts + 10;
send_to_char(C_DEFAULT, "You have been awarded 10 war points for your victory.\n\r", ch);
REMOVE_BIT(d->character->act2, TEAM_RED);
}
if(IS_SET(d->character->act2, TEAM_BLUE))
REMOVE_BIT(d->character->act2, TEAM_BLUE);
}
}
}
}
else if(!IS_SET(victim->act2, PLR_WAR))
{
sprintf(log_buf, "&C%s &chas defeated &C%s &cin the arena!",
ch->name, victim->name);
wiznet(log_buf, NULL, NULL, WIZ_DEATHS, 0, 0);
log_string(log_buf, CHANNEL_LOG, -1);
challenge(log_buf, 0, 0);
ch->arenawon++;
victim->arenalost++;
}
if (warkilled == FALSE)
raw_kill( ch, victim );
/* Ok, now we want to remove the deleted flag from the
* PC victim.
*/
if ( !IS_NPC( victim ) )
victim->deleted = FALSE;
if ( !IS_NPC( ch ) && IS_NPC( victim ) )
{
if ( IS_SET( ch->act, PLR_AUTOLOOT ) )
do_get( ch, "all corpse" );
else
do_look( ch, "in corpse" );
if ( IS_SET( ch->act, PLR_AUTOCOINS ) )
do_get( ch, "all.coin corpse" );
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 )
{
if ( number_range( 0, victim->wait ) == 0 )
{
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 < MAX_HIT(victim) / 2 )
|| ( IS_AFFECTED( victim, AFF_CHARM ) && victim->master
&& 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, "" );
tail_chain( );
return;
}
void item_damage( CHAR_DATA *ch, int dam )
{
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
for ( obj_lose = ch->carrying; obj_lose; obj_lose = obj_next )
{
char *msg;
obj_next = obj_lose->next_content;
if ( obj_lose->deleted )
continue;
if ( number_bits( 2 ) != 0 )
continue;
#ifdef NEW_MONEY
/* Check if total cost in copper is less than 500,000 */
if ( ( (obj_lose->pIndexData->cost.gold*C_PER_G) +
(obj_lose->pIndexData->cost.silver*S_PER_G) +
(obj_lose->pIndexData->cost.copper) ) < 5000*100 )
continue;
#else
if ( obj_lose->pIndexData->cost < 5000 )
continue;
#endif
if ( obj_lose->wear_loc == WEAR_NONE )
continue;
if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) )
continue;
switch ( obj_lose->item_type )
{
default:
msg = "Your $p gets ruined!";
extract_obj( obj_lose );
break;
case ITEM_DRINK_CON:
case ITEM_POTION:
case ITEM_CONTAINER:
case ITEM_LIGHT:
msg = "Your $p shatters!";
extract_obj( obj_lose );
break;
case ITEM_WEAPON:
case ITEM_ARMOR:
#ifdef NEW_MONEY
/* if ( ( obj_lose->cost.gold +
(obj_lose->cost.silver/SILVER_PER_GOLD) +
(obj_lose->cost.copper/COPPER_PER_GOLD) ) != 0 )
*/
if ( ( (obj_lose->cost.gold*100) +
(obj_lose->cost.silver*10) +
(obj_lose->cost.copper) ) != 0 )
{
obj_lose->cost.gold = ( obj_lose->cost.gold > 0 ) ?
(obj_lose->cost.gold - dam/6) : 0;
obj_lose->cost.silver = ( obj_lose->cost.silver > 0 ) ?
(obj_lose->cost.silver - dam/6) : 0;
obj_lose->cost.copper = ( obj_lose->cost.copper > 0 ) ?
(obj_lose->cost.copper - dam/6) : 0;
}
/* if ( (obj_lose->cost.gold +
(obj_lose->cost.silver/SILVER_PER_GOLD) +
(obj_lose->cost.copper/COPPER_PER_GOLD) ) < 0 )
*/
if ( ( (obj_lose->cost.gold*100) +
(obj_lose->cost.silver*10) +
(obj_lose->cost.copper) ) < 0 )
#else
if ( obj_lose->cost != 0 )
obj_lose->cost -= dam/6;
if (obj_lose->cost < 0)
#endif
{
OBJ_DATA *pObj;
OBJ_INDEX_DATA *pObjIndex;
char *name;
char buf[MAX_STRING_LENGTH];
pObjIndex = get_obj_index(4);
pObj = create_object(pObjIndex, obj_lose->level);
name = obj_lose->short_descr;
sprintf(buf, pObj->description, name);
free_string(pObj->description);
pObj->description = str_dup(buf);
pObj->weight = obj_lose->weight;
pObj->timer = obj_lose->level;
msg = "$p has been destroyed!";
extract_obj( obj_lose );
obj_to_room ( pObj, ch->in_room );
}
else
{
msg = "$p has been damaged!";
}
break;
}
act(AT_YELLOW, msg, ch, obj_lose, NULL, TO_CHAR );
return;
}
return;
}
bool is_safe( CHAR_DATA *ch, CHAR_DATA *victim )
{
CLAN_DATA *pClan;
if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) ||
IS_SET( victim->in_room->room_flags, ROOM_SAFE ) )
return TRUE;
if ( !IS_NPC(ch) && !IS_NPC(victim) &&
(IS_SET(ch->in_room->room_flags, ROOM_NO_PKILL) ||
IS_SET(victim->in_room->room_flags, ROOM_NO_PKILL)) )
return TRUE;
if ( IS_AFFECTED( ch, AFF_PEACE ) )
return TRUE;
if ( IS_SET( ch->in_room->room_flags, ROOM_PKILL ) &&
IS_SET( victim->in_room->room_flags, ROOM_PKILL ) )
return FALSE;
if ( IS_NPC( victim ) )
return FALSE;
if ( IS_SET( victim->act, PLR_THIEF )
&& ( ch->guild && !strcmp( ch->guild->name, "MERCENARY" ) ) )
return FALSE;
if ( IS_SET( ch->act, PLR_THIEF )
&& ( victim->guild && !strcmp( victim->guild->name, "MERCENARY" ) ) )
/* return FALSE; */
return TRUE;
/* SIGH
if ( !(IS_SET(ch->act, PLR_PKILLER)) || ( (IS_SET(ch->act, PLR_PKILLER)) &&
!(IS_SET(victim->act, PLR_PKILLER)) ) )
{
send_to_char(AT_WHITE, "You cannot pkill unless you are BOTH pkillers!\n\r", ch );
return TRUE;
}
*/
if ( abs(ch->level - victim->level) > 5 && ( !IS_NPC(ch) )
&& (!IS_SET(victim->act2, PLR_WAR)))
{
send_to_char(AT_WHITE, "That is not in the pkill range... valid range is +/- 5 levels.\n\r", ch );
return TRUE;
}
if ( IS_NPC( ch ) )
{
if ( IS_SET(ch->affected_by, AFF_CHARM) && ch->master )
{
CHAR_DATA *nch;
for ( nch = ch->in_room->people; nch; nch = nch->next )
if ( nch == ch->master )
break;
if ( nch == NULL )
return FALSE;
else
ch = nch; /* Check person who ordered mob for clan stuff.. */
}
else
return FALSE;
}
/* give pkill guilds ability to pkill */
/* Err.. we might not want pkill guilds attacking unguilded.. */
if ( (ch->guild && (ch->guild->type & GUILD_PKILL)) &&
(victim->guild && (victim->guild->type & GUILD_PKILL)) )
{
return FALSE;
}
pClan = get_clan_index( ch->clan );
if ( ( ch->clan == 0 ) && ( !IS_SET(pClan->settings, CLAN_PKILL) )
&& (!IS_SET(victim->act2, PLR_WAR)))
{
send_to_char(AT_WHITE, "You must be clanned to murder.\n\r", ch );
return TRUE;
}
pClan = get_clan_index( victim->clan);
if ( ( victim->clan == 0 ) && ( !IS_SET(pClan->settings, CLAN_PKILL) )
&& (!IS_SET(victim->act2, PLR_WAR)))
{
send_to_char(AT_WHITE, "You can only murder clanned players.\n\r",ch);
return TRUE;
}
pClan = get_clan_index( ch->clan );
if ( ch->clan == victim->clan &&
IS_SET( pClan->settings, CLAN_CIVIL_PKILL) )
{
return FALSE;
}
/* can murder self for testing =) */
if ( ch->clan == victim->clan && ch != victim && ch->clan != 0
&& (!IS_SET(victim->act2, PLR_WAR)))
{
send_to_char(AT_WHITE, "You cannot murder your own clan member.\n\r",ch);
return TRUE;
}
if ( !IS_SET(pClan->settings, CLAN_PKILL)
&& (!IS_SET(victim->act2, PLR_WAR)))
{
send_to_char(AT_WHITE, "Peaceful clan members cannot murder.\n\r",ch);
return TRUE;
}
pClan = get_clan_index( victim->clan );
if ( !IS_SET(pClan->settings, CLAN_PKILL )
&& (!IS_SET(victim->act2, PLR_WAR)))
{
send_to_char(AT_WHITE, "You may not murder peaceful clan members.\n\r",ch);
return TRUE;
}
if ( IS_SET( victim->act, PLR_KILLER ) )
return FALSE;
return FALSE;
}
/*
* See if an attack justifies a KILLER flag.
*/
void check_killer( CHAR_DATA *ch, CHAR_DATA *victim )
{
CLAN_DATA *pClan;
char buf [ MAX_STRING_LENGTH ];
if ( IS_ARENA(victim) )
return;
/*
* NPC's are fair game.
* So are killers and thieves.
*/
if ( IS_NPC( victim )
|| IS_SET( victim->act, PLR_KILLER )
|| IS_SET( victim->act, PLR_THIEF ) )
return;
/*
* NPC's are cool of course
* Hitting yourself is cool too (bleeding).
* And current killers stay as they are.
*/
if ( IS_NPC( ch )
|| ch == victim
|| IS_SET( ch->act, PLR_KILLER )
|| IS_SET( ch->act, PLR_THIEF ) )
return;
pClan = get_clan_index( ch->clan );
if ( /*ch->clan != 0 ||*/ ( IS_SET(pClan->settings, CLAN_PKILL) ) ||
( ch->clan == victim->clan && IS_SET(pClan->settings, CLAN_CIVIL_PKILL)) )
return;
send_to_char(AT_RED, "*** You are now a KILLER!! ***\n\r", ch );
sprintf(buf,"$N is attempting to murder %s",victim->name);
wiznet(buf,ch,NULL,WIZ_FLAGS,0,0);
SET_BIT(ch->act, PLR_KILLER);
save_char_obj( ch, FALSE );
return;
}
bool is_bare_hand( CHAR_DATA *ch )
{
if ( !get_eq_char( ch, WEAR_WIELD )
&& !get_eq_char( ch, WEAR_WIELD_2 ) )
return TRUE;
return FALSE;
}
/*
* Check to see if weapon is poisoned.
*/
bool is_wielding_poisoned( CHAR_DATA *ch )
{
OBJ_DATA *obj;
if ( ( obj = get_eq_char( ch, WEAR_WIELD ) )
&& IS_SET( obj->extra_flags, ITEM_POISONED ) )
return TRUE;
return FALSE;
}
bool is_wielding_flaming( CHAR_DATA *ch )
{
OBJ_DATA *obj;
if ( ( obj = get_eq_char( ch, WEAR_WIELD ) )
&& IS_SET( obj->extra_flags, ITEM_FLAME ) )
return TRUE;
return FALSE;
}
bool is_wielding_icy( CHAR_DATA *ch )
{
OBJ_DATA *obj;
if ( ( obj = get_eq_char( ch, WEAR_WIELD ) )
&& IS_SET( obj->extra_flags, ITEM_ICY ) )
return TRUE;
return FALSE;
}
bool is_wielding_chaos( CHAR_DATA *ch )
{
OBJ_DATA *obj;
if ( ( obj = get_eq_char( ch, WEAR_WIELD ) )
&& IS_SET( obj->extra_flags, ITEM_CHAOS ) )
return TRUE;
return FALSE;
}
/*
* Check for parry.
*/
bool check_parry( CHAR_DATA *ch, CHAR_DATA *victim )
{
int chance;
if ( !IS_AWAKE( victim ) )
return FALSE;
if ( IS_NPC( victim ) )
{
/* Tuan was here. :) */
chance = UMIN( 60, 2 * victim->level );
if ( !get_eq_char( victim, WEAR_WIELD ) )
chance = chance / 2;
}
else
{
if ( !get_eq_char( victim, WEAR_WIELD ) )
return FALSE;
chance = victim->pcdata->learned[gsn_parry] / 2;
}
if ( ch->wait != 0 )
chance /= 4;
if ( number_percent( ) >= chance + victim->level - ch->level )
return FALSE;
update_skpell( ch, gsn_parry );
if ( IS_SET( ch->act, PLR_COMBAT ) )
act(AT_GREEN, "$N parries your attack.", ch, NULL, victim, TO_CHAR );
if ( IS_SET( victim->act, PLR_COMBAT ) )
act(AT_GREEN, "You parry $n's attack.", ch, NULL, victim, TO_VICT );
return TRUE;
}
/*
* Check for dodge.
*/
bool check_dodge( CHAR_DATA *ch, CHAR_DATA *victim )
{
int chance;
if ( !IS_AWAKE( victim ) )
return FALSE;
if ( IS_NPC( victim ) )
/* Tuan was here. :) */
chance = UMIN( 60, 2 * victim->level );
else
chance = victim->pcdata->learned[gsn_dodge] / 2
+ victim->pcdata->learned[gsn_dodge_two] / 2;
if ( ch->wait != 0 )
chance /= 4;
if ( number_percent( ) >= chance + victim->level - ch->level )
return FALSE;
update_skpell( ch, gsn_dodge );
update_skpell( ch, gsn_dodge_two );
if ( IS_SET( ch->act, PLR_COMBAT ) )
act(AT_GREEN, "$N dodges your attack.", ch, NULL, victim, TO_CHAR );
if ( IS_SET( victim->act, PLR_COMBAT ) )
act(AT_GREEN, "You dodge $n's attack.", ch, NULL, victim, TO_VICT );
return TRUE;
}
bool check_sidestep( CHAR_DATA *ch, CHAR_DATA *victim )
{
int chance;
if ( !IS_AWAKE( victim ) )
return FALSE;
if ( IS_NPC( victim ) )
/* Tuan was here. :) */
return FALSE;
if ( victim->race != RACE_SHADOW )
return FALSE;
chance = 50;
if ( number_percent( ) >= chance + victim->level - ch->level )
return FALSE;
if ( IS_SET( ch->act, PLR_COMBAT ) )
act(AT_GREEN, "$N sidesteps your attack.", ch, NULL, victim, TO_CHAR );
if ( IS_SET( victim->act, PLR_COMBAT ) )
act(AT_GREEN, "You sidestep $n's attack.", ch, NULL, victim, TO_VICT );
return TRUE;
}
/*
* Set position of a victim.
*/
void update_pos( CHAR_DATA *victim )
{
if ( victim->hit > 0 )
{
if ( victim->position < POS_STUNNED )
victim->position = POS_STANDING;
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 [ MAX_STRING_LENGTH ];
if ( ch->fighting )
{
bug( "Set_fighting: already fighting", 0 );
sprintf( buf, "...%s attacking %s at %d",
( IS_NPC( ch ) ? ch->short_descr : ch->name ),
( IS_NPC( victim ) ? victim->short_descr : victim->name ),
victim->in_room->vnum );
bug( buf , 0 );
return;
}
if ( IS_AFFECTED( ch, AFF_SLEEP ) )
affect_strip( ch, gsn_sleep );
ch->fighting = victim;
ch->position = POS_FIGHTING;
return;
}
/*
* Stop fights.
*/
void stop_fighting( CHAR_DATA *ch, bool fBoth )
{
CHAR_DATA *fch;
for ( fch = char_list; fch; fch = fch->next )
{
if ( fch == ch || ( fBoth && fch->fighting == ch ) )
{
fch->fighting = NULL;
fch->hunting = NULL;
fch->position = POS_STANDING;
if ( is_affected( fch, gsn_berserk ) )
{
affect_strip( fch, gsn_berserk );
send_to_char(C_DEFAULT, skill_table[gsn_berserk].msg_off,fch);
send_to_char(C_DEFAULT, "\n\r",fch);
act(C_DEFAULT, skill_table[gsn_berserk].room_msg_off,fch,
NULL, NULL, TO_ROOM);
}
else if ( is_affected( fch, gsn_frenzy ) )
{
affect_strip( fch, gsn_frenzy );
send_to_char(C_DEFAULT, skill_table[gsn_frenzy].msg_off,fch);
send_to_char(C_DEFAULT, "\n\r",fch);
act(C_DEFAULT,skill_table[gsn_frenzy].room_msg_off,fch,
NULL, NULL, TO_ROOM);
}
if ( IS_AFFECTED2(fch, AFF_BERSERK) )
REMOVE_BIT(fch->affected_by2, AFF_BERSERK);
update_pos( fch );
}
}
return;
}
/*
* Make a corpse out of a character.
*/
void make_corpse( CHAR_DATA *ch )
{
OBJ_DATA *corpse;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
/* ROOM_INDEX_DATA *location;*/
char *name;
char buf [ MAX_STRING_LENGTH ];
OBJ_DATA *random;
int level = ch->level;
/* No corpses in the arena. -- Altrag */
if ( IS_ARENA(ch) )
{
CHAR_DATA *gch = (ch == arena.fch ? arena.sch : arena.fch);
int award;
/* Arena master takes 1/5.. *wink* */
award = (arena.award * 4) / 5;
sprintf(log_buf, "&C%s &chas been awarded &W%d &ccoins for %s victory.",
gch->name, award, (gch->sex == SEX_NEUTRAL ? "its" :
(gch->sex == SEX_MALE ? "his" : "her")));
/* wiznet(log_buf, NULL, NULL, WIZ_DEATHS, 0, 0); */
log_string(log_buf, CHANNEL_LOG, -1);
challenge(log_buf, 0, 0);
#ifdef NEW_MONEY
gch->money.gold += award;
#else
gch->gold += award;
#endif
sprintf(log_buf, "You have been awarded %d gold coins for your victory."
"\n\r", award);
send_to_char(AT_YELLOW, log_buf, gch);
char_from_room(gch);
char_to_room(gch, get_room_index(ROOM_VNUM_ALTAR));
return;
}
if ( !IS_NPC( ch ) && ch->level <= 20 )
{
char_from_room( ch );
char_to_room( ch, get_room_index(ROOM_VNUM_MORGUE) );
}
if ( IS_NPC( ch ) )
{
/*
* This longwinded corpse creation routine comes about because
* we dont want anything created AFTER a corpse to be placed
* INSIDE a corpse. This had caused crashes from obj_update()
* in extract_obj() when the updating list got shifted from
* object_list to obj_free. --- Thelonius (Monk)
*/
#ifdef NEW_MONEY
if ( (ch->money.gold > 0) || (ch->money.silver > 0) ||
(ch->money.copper > 0) )
#else
if ( ch->gold > 0 )
#endif
{
OBJ_DATA * coins;
#ifdef NEW_MONEY
coins = create_money( &ch->money );
#else
coins = create_money( ch->gold );
#endif
name = ch->short_descr;
corpse = create_object(
get_obj_index( OBJ_VNUM_CORPSE_NPC ),
0 );
corpse->timer = number_range( 2, 4 );
obj_to_obj( coins, corpse );
#ifdef NEW_MONEY
ch->money.gold = ch->money.silver = ch->money.copper = 0;
#else
ch->gold = 0;
#endif
}
else
{
name = ch->short_descr;
corpse = create_object(
get_obj_index( OBJ_VNUM_CORPSE_NPC ),
0 );
corpse->timer = number_range( 2, 4 );
}
}
else
{
name = ch->name;
corpse = create_object(
get_obj_index( OBJ_VNUM_CORPSE_PC ),
0 );
corpse->timer = number_range( 25, 40 );
#ifdef NEW_MONEY
/* Check if ch has any money, doesn't matter about converting */
if ( ( ( ch->money.gold + ch->money.silver +
ch->money.copper ) > 0 ) &&
( ch->level > 5 ) )
{
OBJ_DATA * coins;
coins = create_money( &ch->money );
obj_to_obj( coins, corpse );
ch->money.gold = ch->money.silver = ch->money.copper = 0;
}
#else
if ( ( ch->gold > 0 ) && ( ch->level > 5 ) )
{
OBJ_DATA * coins;
coins = create_money( ch->gold );
obj_to_obj( coins, corpse );
ch->gold = 0;
}
#endif
}
sprintf( buf, corpse->short_descr, name );
free_string( corpse->short_descr );
corpse->short_descr = str_dup( buf );
sprintf( buf, corpse->description, name );
free_string( corpse->description );
corpse->description = str_dup( buf );
for ( obj = ch->carrying; obj; obj = obj_next )
{
obj_next = obj->next_content;
if ( obj->deleted )
continue;
obj_from_char( obj );
if ( IS_SET( obj->extra_flags, ITEM_INVENTORY ) )
extract_obj( obj );
else
obj_to_obj( obj, corpse );
}
if ( (number_percent() > 50) && IS_NPC(ch) )
{
random = random_object( level );
obj_to_obj( random, corpse );
}
/* sprintf( buf, "NPC killed: %s -> %d", ch->name, ch->in_room->vnum );
log_string( buf, CHANNEL_NONE, -1 );
wiznet(buf,NULL,NULL,WIZ_MOBDEATHS,0,0);*/
if ( ( IS_NPC( ch ) ) && ( !IS_SET( ch->act, UNDEAD_TYPE( ch ) ) ) )
corpse->ac_vnum=ch->pIndexData->vnum;
obj_to_room( corpse, ch->in_room );
if ( !IS_NPC( ch ) )
corpse_back( ch, corpse );
return;
}
/*
* Improved Death_cry contributed by Diavolo.
*/
void death_cry( CHAR_DATA *ch )
{
ROOM_INDEX_DATA *was_in_room;
char *msg;
int vnum;
int door;
OBJ_DATA *obj;
if ( IS_ARENA(ch) )
return;
vnum = 0;
switch ( number_bits( 4 ) )
{
default: msg = "You hear $n's death cry."; break;
case 0: msg = "$n hits the ground ... DEAD."; break;
case 1: msg = "$n splatters blood on your armor."; break;
case 2: msg = "$n's innards fall to the ground with a wet splat."; break;
case 3: msg = "$n's severed head plops on the ground.";
vnum = OBJ_VNUM_SEVERED_HEAD; break;
case 4: msg = "$n's heart is torn from $s chest.";
vnum = OBJ_VNUM_TORN_HEART; break;
case 5: msg = "$n's arm is sliced from $s dead body.";
vnum = OBJ_VNUM_SLICED_ARM; break;
case 6: msg = "$n's leg is sliced from $s dead body.";
vnum = OBJ_VNUM_SLICED_LEG; break;
}
act(AT_BLOOD, msg, ch, NULL, NULL, TO_ROOM );
if ( vnum != 0 )
{
char *name;
char buf [ MAX_STRING_LENGTH ];
name = IS_NPC( ch ) ? ch->short_descr : ch->name;
obj = create_object( get_obj_index( vnum ), 0 );
obj->timer = number_range( 4, 7 );
sprintf( buf, obj->short_descr, name );
free_string( obj->short_descr );
obj->short_descr = str_dup( buf );
sprintf( buf, obj->description, name );
free_string( obj->description );
obj->description = str_dup( buf );
obj_to_room( obj, ch->in_room );
}
obj = create_object( get_obj_index(OBJ_VNUM_FINAL_TURD), 0 );
obj->timer = number_range( 3, 5 );
obj_to_room( obj, ch->in_room );
if ( IS_NPC( ch ) )
msg = "You hear something's death cry.";
else
msg = "You hear someone's death cry.";
was_in_room = ch->in_room;
for ( door = 0; door <= 5; door++ )
{
EXIT_DATA *pexit;
if ( ( pexit = was_in_room->exit[door] )
&& pexit->to_room
&& pexit->to_room != was_in_room )
{
ch->in_room = pexit->to_room;
act(AT_BLOOD, msg, ch, NULL, NULL, TO_ROOM );
}
}
ch->in_room = was_in_room;
return;
}
void raw_kill( CHAR_DATA *ch, CHAR_DATA *victim )
{
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
bool is_arena = IS_ARENA(ch);
stop_fighting( victim, TRUE );
if ( ch != victim )
mprog_death_trigger( victim, ch );
rprog_death_trigger( victim->in_room, victim );
make_corpse( victim );
for ( paf = victim->affected; paf; paf = paf_next )
{
paf_next = paf->next;
affect_remove( victim, paf );
}
for ( paf = victim->affected2; paf; paf = paf_next )
{
paf_next = paf->next;
affect_remove2( victim, paf );
}
victim->affected_by = 0;
victim->affected_by2 = 0;
if ( IS_NPC( victim ) )
{
victim->pIndexData->killed++;
kill_table[URANGE( 0, victim->level, MAX_LEVEL-1 )].killed++;
extract_char( victim, TRUE );
return;
}
extract_char( victim, FALSE );
if ( !is_arena )
{
victim->armor = 100;
victim->hitroll = 0;
victim->damroll = 0;
victim->saving_throw = 0;
victim->carry_weight = 0;
victim->carry_number = 0;
}
victim->position = POS_RESTING;
victim->hit = UMAX( 1, victim->hit );
victim->mana = UMAX( 1, victim->mana );
victim->bp = UMAX( 1, victim->bp );
victim->move = UMAX( 1, victim->move );
save_char_obj( victim, FALSE );
return;
}
void war_kill( CHAR_DATA *victim )
{
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
stop_fighting( victim, TRUE );
rprog_death_trigger( victim->in_room, victim );
char_from_room(victim);
char_to_room(victim, get_room_index(ROOM_VNUM_MORGUE));
for ( paf = victim->affected; paf; paf = paf_next )
{
paf_next = paf->next;
affect_remove( victim, paf );
}
for ( paf = victim->affected2; paf; paf = paf_next )
{
paf_next = paf->next;
affect_remove2( victim, paf );
}
REMOVE_BIT( victim->act2, PLR_WAR );
if (IS_SET( victim->act2, TEAM_RED ))
REMOVE_BIT( victim->act2, TEAM_RED );
if (IS_SET( victim->act2, TEAM_BLUE ))
REMOVE_BIT( victim->act2, TEAM_BLUE );
victim->affected_by = 0;
victim->affected_by2 = 0;
victim->position = POS_RESTING;
victim->hit = UMAX( 1, victim->hit );
victim->mana = UMAX( 1, victim->mana );
victim->bp = UMAX( 1, victim->bp );
victim->move = UMAX( 1, victim->move );
save_char_obj( victim, FALSE );
return;
}
void group_gain( CHAR_DATA *ch, CHAR_DATA *victim )
{
CHAR_DATA *gch;
CHAR_DATA *lch;
char buf[ MAX_STRING_LENGTH ];
int members;
int xp;
/*
* Monsters don't get kill xp's or alignment changes.
* P-killing doesn't help either.
* Dying of mortal wounds or poison doesn't give xp to anyone!
*/
if ( IS_NPC( ch ) || victim == ch )
return;
members = 0;
for ( gch = ch->in_room->people; gch; 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 ) ? ch->leader : ch;
for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
{
OBJ_DATA *obj;
OBJ_DATA *obj_next;
if ( !is_same_group( gch, ch ) )
continue;
if ( gch->level - lch->level >= 6 )
{
send_to_char(AT_BLUE, "You are too high level for this group.\n\r", gch );
continue;
}
if ( gch->level - lch->level <= -6 )
{
send_to_char(AT_BLUE, "You are too low level for this group.\n\r", gch );
continue;
}
xp = xp_compute( gch, victim ) / members;
/* sprintf( buf, "%s -> gains %dxp", gch->name, xp);
log_string( buf, CHANNEL_NONE, -1 );*/
sprintf( buf, "You receive %d experience points.\n\r", xp );
send_to_char(AT_WHITE, buf, gch );
gain_exp( gch, xp );
for ( obj = ch->carrying; obj; obj = obj_next )
{
obj_next = obj->next_content;
if ( obj->deleted )
continue;
if ( obj->wear_loc == WEAR_NONE )
continue;
if ( !IS_NPC( ch ) )
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(AT_BLUE, "You are zapped by $p.", ch, obj, NULL, TO_CHAR );
act(AT_BLUE, "$n is zapped by $p.", ch, obj, NULL, TO_ROOM );
obj_from_char( obj );
obj_to_room( obj, ch->in_room );
}
}
}
if ( IS_SET(ch->act, PLR_QUESTOR ) && IS_NPC( victim ))
{
if ( ch->questmob && victim == ch->questmob )
{
send_to_char(AT_WHITE, "You have almost completed your QUEST!\n\r", ch);
send_to_char(AT_WHITE, "Return to the QuestMaster before your time runs out!\n\r", ch );
ch->questmob = NULL;
}
}
return;
}
/*
* Compute xp for a kill.
* Also adjust alignment of killer.
* Edit this function to change xp computations.
* NOTE: New xp system by Hannibal
*/
int xp_compute( CHAR_DATA *gch, CHAR_DATA *victim )
{
int xp;
int xp_cap = 750;
int align;
align = gch->alignment - victim->alignment;
if ( align > 500 )
gch->alignment = UMIN( gch->alignment + ( align - 500 ) / 4, 1000 );
else if ( align < -500 )
gch->alignment = UMAX( gch->alignment + ( align + 500 ) / 4, -1000 );
else
gch->alignment -= victim->alignment / 3;
/* mob lvl is 5 lvls lower than pc or more */
if ( victim->level + 5 <= gch->level )
return 0;
/* 3-4 levels lower */
if ( victim->level + 3 == gch->level
|| victim->level + 4 == gch->level )
{
xp = ( gch->level < 10 ) ? number_range( 50, 100 ) + 10 : 0;
return xp;
}
/* if same lvl or up to 2 lvls lower */
if ( victim->level > gch->level - 3
&& victim->level <= gch->level )
{
xp = number_range( 0, 10 ) + number_range( 10, 15 );
xp = ( gch->level < 10 ) ? xp + number_range( 50, 100 ) : xp;
return xp;
}
/* if higher lvl then... */
xp = ( victim->level - gch->level ) * number_range( 25, 40 );
xp = ( gch->level < 10 ) ? xp + number_range( 35, 50 ) : xp;
/* if they kill 5 lvls bigger then them or more add 0-50xp */
xp = ( victim->level >= gch->level + 5 ) ? xp + number_range( 0, 50 )
: xp;
/* Enforce xp cap */
xp = UMIN( xp_cap, xp );
xp = UMAX( 0, xp );
/* Xp Boost */
if ( doubleexp() == TRUE && gch->level <= 15)
xp = xp * 4;
else if ( doubleexp() == TRUE && gch->level <= 30 && gch->level > 15)
xp = xp * 3;
else if ( doubleexp() == TRUE && gch->level <= 50 && gch->level > 30)
xp = xp * 2;
return xp;
/* OLD xp system
int xp;
int align;
int extra;
int level;
int number;
xp = 150 - URANGE( -10, gch->level - victim->level, 10 ) * 30;
align = gch->alignment - victim->alignment;
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 );
xp = 5 * xp / 4;
}
else
{
gch->alignment -= victim->alignment / 3;
xp = 3 * xp / 4;
}
*/
/*
* Adjust for popularity of target:
* -1/8 for each target over 'par' (down to - 50%)
* +1/8 for each target under 'par' ( up to + 25%)
*/
/* level = URANGE( 0, victim->level, 99 );
number = UMAX( 1, kill_table[level].number );
if(IS_NPC(victim))
extra = victim->pIndexData->killed - kill_table[level].killed / number;
else
extra = 0;
xp -= xp * URANGE( -2, extra, 4 ) / 8;
xp = number_range( xp * 3 / 4, xp * 5 / 4 );
xp = UMAX( 0, xp );
return xp;
*/
}
void dam_message( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt )
{
static char * const attack_table [ ] =
{
"hit",
"slice", "stab", "slash", "whip", "claw",
"blast", "pound", "crush", "grep", "bite",
"pierce", "suction", "chop", "left fist", "right fist"
};
const char *vs;
const char *vp;
const char *attack;
char buf [ MAX_STRING_LENGTH ];
char buf1 [ 256 ];
char buf2 [ 256 ];
char buf3 [ 256 ];
char buf4 [ 256 ];
char buf5 [ 256 ];
char punct;
if ( dam == 0 ) { vs = "miss"; vp = "misses"; }
else if ( dam <= 4 ) { vs = "scratch"; vp = "scratches"; }
else if ( dam <= 8 ) { vs = "graze"; vp = "grazes"; }
else if ( dam <= 12 ) { vs = "hit"; vp = "hits"; }
else if ( dam <= 16 ) { vs = "injure"; vp = "injures"; }
else if ( dam <= 20 ) { vs = "wound"; vp = "wounds"; }
else if ( dam <= 24 ) { vs = "maul"; vp = "mauls"; }
else if ( dam <= 28 ) { vs = "decimate"; vp = "decimates"; }
else if ( dam <= 32 ) { vs = "devastate"; vp = "devastates"; }
else if ( dam <= 36 ) { vs = "maim"; vp = "maims"; }
else if ( dam <= 40 ) { vs = "MUTILATE"; vp = "MUTILATES"; }
else if ( dam <= 44 ) { vs = "DISEMBOWEL"; vp = "DISEMBOWELS"; }
else if ( dam <= 48 ) { vs = "EVISCERATE"; vp = "EVISCERATES"; }
else if ( dam <= 52 ) { vs = "MASSACRE"; vp = "MASSACRES"; }
else if ( dam <= 100 ) { vs = "*** DEMOLISH ***";
vp = "*** DEMOLISHES ***"; }
else if ( dam <= 150 ) { vs = "*** DEVASTATE ***";
vp = "*** DEVASTATES ***"; }
else if ( dam <= 250 ) { vs = "*** OBLITERATE ***";
vp = "*** OBLITERATES ***"; }
else if ( dam <= 300 ) { vs = "=== OBLITERATE ===";
vp = "=== OBLITERATES ==="; }
else if ( dam <= 500 ) { vs = "*** ANNIHILATE ***";
vp = "*** ANNIHILATES ***"; }
else if ( dam <= 750 ) { vs = ">>> ANNIHILATE <<<";
vp = ">>> ANNIHILATES <<<"; }
else if ( dam <= 1000) { vs = "<<< ERADICATE >>>";
vp = "<<< ERADICATES >>>"; }
else { vs = "&Xdo &rUNSPEAKABLE&X things to";
vp = "&Xdoes &rUNSPEAKABLE&X things to";
}
punct = ( dam <= 24 ) ? '.' : '!';
if ( dt == TYPE_HIT )
{
sprintf( buf1, "You &r%s&X $N%c (%d)", vs, punct, dam );
sprintf( buf2, "$n &G%s&X you%c (%d)", vp, punct, dam );
sprintf( buf3, "$n &z%s&X $N%c (%d)", vp, punct, dam );
sprintf( buf4, "You &G%s&X yourself%c (%d)", vs, punct, dam );
sprintf( buf5, "$n &z%s&X $mself%c (%d)", vp, punct, dam );
}
else
{
if ( is_sn(dt) )
attack = skill_table[dt].noun_damage;
else if ( dt >= TYPE_HIT
&& dt < TYPE_HIT
+ sizeof( attack_table )/sizeof( attack_table[0] ) )
attack = attack_table[dt - TYPE_HIT];
else
{
sprintf( buf, "Dam_message: bad dt %d caused by %s.", dt,
ch->name );
bug( buf, 0 );
dt = TYPE_HIT;
attack = attack_table[0];
}
if ( dt > TYPE_HIT && is_wielding_poisoned( ch ) )
{
sprintf( buf1, "Your &gpoisoned&X %s &r%s&X $N%c (%d)", attack, vp,punct, dam );
sprintf( buf2, "$n's &gpoisoned&X %s &G%s&X you%c (%d)", attack, vp,punct, dam );
sprintf( buf3, "$n's &gpoisoned&X %s &z%s&X $N%c (%d)", attack, vp,punct, dam );
sprintf( buf4, "Your &gpoisoned&X %s &G%s&X you%c (%d)", attack, vp,punct, dam );
sprintf( buf5, "$n's &gpoisoned&X %s &z%s&X $n%c (%d)", attack, vp,punct, dam );
}
else
{
sprintf( buf1, "Your %s &r%s&X $N%c (%d)", attack, vp, punct,dam );
sprintf( buf2, "$n's %s &G%s&X you%c (%d)", attack, vp, punct,dam );
sprintf( buf3, "$n's %s &z%s&X $N%c (%d)", attack, vp, punct,dam );
sprintf( buf4, "Your %s &G%s&X you%c (%d)", attack, vp, punct,dam );
sprintf( buf5, "$n's %s &z%s&X $n%c (%d)", attack, vp, punct,dam );
}
}
if ( victim != ch )
{
if ( dam != 0 || IS_SET( ch->act, PLR_COMBAT ) )
act(AT_WHITE, buf1, ch, NULL, victim, TO_CHAR );
if ( dam != 0 || IS_SET( victim->act, PLR_COMBAT ) )
act(AT_WHITE, buf2, ch, NULL, victim, TO_VICT );
act(AT_GREY, buf3, ch, NULL, victim,
dam == 0 ? TO_COMBAT : TO_NOTVICT );
}
else
{
if ( dam != 0 || IS_SET( ch->act, PLR_COMBAT ) )
act(AT_WHITE, buf4, ch, NULL, victim, TO_CHAR );
act(AT_GREY, buf5, ch, NULL, victim,
dam == 0 ? TO_COMBAT : TO_NOTVICT );
}
return;
}
/*
* Disarm a creature.
* Caller must check for successful attack.
*/
void disarm( CHAR_DATA *ch, CHAR_DATA *victim )
{
OBJ_DATA *obj;
if ( !( obj = get_eq_char( victim, WEAR_WIELD ) ) )
if ( !( obj = get_eq_char( victim, WEAR_WIELD_2 ) ) )
if ( !( obj = get_eq_char( victim, WEAR_WIELD_3 ) ) )
return;
if ( !get_eq_char( ch, WEAR_WIELD ) && number_bits( 1 ) == 0 )
if ( !get_eq_char( ch, WEAR_WIELD_2 ) && number_bits( 1 ) == 0 )
if ( !get_eq_char( ch, WEAR_WIELD_3 ) && number_bits( 1 ) == 0 )
return;
act(AT_YELLOW, "You disarm $N!", ch, NULL, victim, TO_CHAR );
act(AT_YELLOW, "$n DISARMS you!", ch, NULL, victim, TO_VICT );
act(AT_GREY, "$n DISARMS $N!", ch, NULL, victim, TO_NOTVICT );
obj_from_char( obj );
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 )
{
if ( ( IS_AFFECTED( victim, AFF_FLYING ) )
|| (victim->race == RACE_PIXIE )
|| (victim->race == RACE_ELDER ) )
return;
if ( !IS_STUNNED( victim, STUN_COMMAND ) && !IS_STUNNED(ch, STUN_TO_STUN) )
{
act(AT_CYAN, "You trip $N and $N goes down!", ch, NULL, victim, TO_CHAR );
act(AT_CYAN, "$n trips you and you go down!", ch, NULL, victim, TO_VICT );
act(AT_GREY, "$n trips $N and $N goes down!", ch, NULL, victim, TO_NOTVICT );
WAIT_STATE( ch, PULSE_VIOLENCE );
STUN_CHAR(victim, 2, STUN_COMMAND);
STUN_CHAR(ch, 3, STUN_TO_STUN);
victim->position = POS_RESTING;
}
return;
}
void do_kill( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
one_argument( argument, arg );
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char( AT_WHITE, "That person is not here.\n\r", ch );
return;
}
if ( is_safe( ch, victim ) )
{
send_to_char( AT_WHITE, "You cannot.\n\r", ch );
return;
}
if ( arg[0] == '\0' )
{
send_to_char(AT_WHITE, "Kill whom?\n\r", ch );
return;
}
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(AT_WHITE, "They aren't here.\n\r", ch );
return;
}
if ( is_affected( victim, gsn_image ))
{
do_image( victim, ch );
affect_strip( victim, skill_lookup("image"));
REMOVE_BIT( victim->affected_by, gsn_image );
return;
}
if ( IS_AFFECTED(victim, AFF_PEACE ))
{
send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch);
return;
}
if ( IS_AFFECTED( ch, AFF_PEACE ) )
{
affect_strip( ch, skill_lookup("aura of peace" ));
REMOVE_BIT( ch->affected_by, AFF_PEACE );
}
if ( !IS_NPC( victim ) && !IS_ARENA(victim) )
{
if ( !IS_SET( victim->act, PLR_KILLER )
&& !IS_SET( victim->act, PLR_THIEF )
&& !IS_SET( victim->act2, PLR_WAR ))
{
send_to_char(AT_WHITE, "You must MURDER a player.\n\r", ch );
return;
}
}
else
{
if ( IS_AFFECTED( victim, AFF_CHARM ) && victim->master )
{
send_to_char(AT_WHITE, "You must MURDER a charmed creature.\n\r", ch );
return;
}
}
if ( victim == ch )
{
send_to_char(AT_RED, "You hit yourself. Stupid!\n\r", ch );
multi_hit( ch, ch, TYPE_UNDEFINED );
return;
}
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim )
{
act(AT_BLUE, "$N is your beloved master!", ch, NULL, victim, TO_CHAR );
return;
}
if ( ch->position == POS_FIGHTING )
{
send_to_char(C_DEFAULT, "You do the best you can!\n\r", ch );
return;
}
WAIT_STATE( ch, PULSE_VIOLENCE );
if ( (!IS_SET( victim->act2, PLR_WAR ) ) )
check_killer( ch, victim );
multi_hit( ch, victim, TYPE_UNDEFINED );
return;
}
void do_murde( CHAR_DATA *ch, char *argument )
{
send_to_char(C_DEFAULT, "If you want to MURDER, spell it out.\n\r", ch );
return;
}
void do_murder( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char buf [ MAX_STRING_LENGTH ];
char arg [ MAX_INPUT_LENGTH ];
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char(C_DEFAULT, "Murder whom?\n\r", ch );
return;
}
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
if ( IS_AFFECTED(victim, AFF_PEACE ))
{
send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch);
return;
}
if ( IS_AFFECTED( ch, AFF_PEACE ))
{
affect_strip( ch, skill_lookup("aura of peace") );
REMOVE_BIT( ch->affected_by, AFF_PEACE );
}
if ( is_affected( victim, gsn_image ))
{
do_image( victim, ch );
affect_strip( victim, skill_lookup("image"));
REMOVE_BIT( victim->affected_by, gsn_image );
return;
}
if ( victim == ch )
{
send_to_char(C_DEFAULT, "Suicide is a mortal sin.\n\r", ch );
return;
}
if ( is_safe( ch, victim ) )
return;
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim )
{
act(C_DEFAULT, "$N is your beloved master!", ch, NULL, victim, TO_CHAR );
return;
}
if ( !IS_SET( ch->act, PLR_PKILLER ) && !IS_ARENA( ch ) &&
!IS_NPC( victim ) ) /* chars can murder mobs */
{
send_to_char(C_DEFAULT,
"You must be a Pkiller to kill another mortal!\n\r", ch );
return;
}
if ( !IS_SET( victim->act, PLR_PKILLER ) && !IS_ARENA( victim )
&& !IS_NPC( victim ) ) /* chars can murder mobs */
{
send_to_char(C_DEFAULT, "You can only pkill other Pkillers.\n\r", ch );
return;
}
if ( ch->position == POS_FIGHTING )
{
send_to_char(C_DEFAULT, "You do the best you can!\n\r", ch );
return;
}
WAIT_STATE( ch, PULSE_VIOLENCE );
if ( !IS_NPC( victim ) )
{
sprintf( buf, "Help! I am being attacked by %s!", ch->name );
do_shout( victim, buf );
}
multi_hit( ch, victim, TYPE_UNDEFINED );
return;
}
void do_backstab( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *obj;
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_backstab ) )
{
send_to_char(C_DEFAULT,
"You better leave the assassin trade to thieves.\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char(C_DEFAULT, "Backstab whom?\n\r", ch );
return;
}
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
if ( victim == ch )
{
send_to_char(C_DEFAULT, "How can you sneak up on yourself?\n\r", ch );
return;
}
if ( is_safe( ch, victim ) )
return;
if ( !( obj = get_eq_char( ch, WEAR_WIELD ) )
|| ( obj->value[3] != 11 && obj->value[3] != 2 ) )
{
send_to_char(C_DEFAULT, "You need to wield a piercing or stabbing weapon.\n\r", ch );
return;
}
if ( is_affected( victim, gsn_image ))
{
do_image( victim, ch );
affect_strip( victim, skill_lookup("image"));
REMOVE_BIT( victim->affected_by, gsn_image );
return;
}
if ( victim->fighting )
{
send_to_char(C_DEFAULT, "You can't backstab a fighting person.\n\r", ch );
return;
}
if ( victim->hit < MAX_HIT(victim) * 0.4 )
{
act(C_DEFAULT, "$N is hurt and suspicious ... you can't sneak up.",
ch, NULL, victim, TO_CHAR );
return;
}
check_killer( ch, victim );
WAIT_STATE( ch, skill_table[gsn_backstab].beats );
if ( !IS_AWAKE( victim )
|| IS_NPC( ch )
|| number_percent( ) < ch->pcdata->learned[gsn_backstab] )
{
multi_hit( ch, victim, gsn_backstab );
update_skpell( ch, gsn_backstab );
if ( ( obj = get_eq_char( ch, WEAR_WIELD_2 ) )
&& ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_backstab_2] > 0 )
&& ( obj->value[3] == 11 || obj->value[3] == 2 ) )
{
multi_hit( ch, victim, gsn_backstab );
update_skpell( ch, gsn_backstab_2 );
if ( get_eq_char( ch, WEAR_WIELD_3 ))
multi_hit( ch, victim, gsn_backstab );
}
}
else
damage( ch, victim, 0, gsn_backstab );
return;
}
void do_assasinate( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *obj;
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if (ch->clan != 4)
{
send_to_char( C_DEFAULT, "Huh?\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char(C_DEFAULT, "Assasinate whom?\n\r", ch );
return;
}
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
if ( victim == ch )
{
send_to_char(C_DEFAULT, "How can you sneak up on yourself?\n\r", ch );
return;
}
if ( is_safe( ch, victim ) )
return;
if ( !( obj = get_eq_char( ch, WEAR_WIELD ) )
|| obj->value[3] != 11 )
{
send_to_char(C_DEFAULT, "You need to wield a piercing weapon.\n\r", ch );
return;
}
if ( victim->fighting )
{
send_to_char(C_DEFAULT, "You can't assasinate a fighting person.\n\r", ch );
return;
}
if ( victim->hit < (MAX_HIT(victim)-50) )
{
act(C_DEFAULT, "$N is hurt and suspicious ... you can't sneak up.",
ch, NULL, victim, TO_CHAR );
return;
}
WAIT_STATE( ch, skill_table[gsn_backstab].beats );
multi_hit( ch, victim, gsn_backstab );
return;
}
void do_flee( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
ROOM_INDEX_DATA *was_in;
ROOM_INDEX_DATA *now_in;
int attempt;
if ( IS_AFFECTED( ch, AFF_ANTI_FLEE ) )
{
send_to_char( AT_RED, "You cannot!\n\r", ch );
return;
}
if ( !( victim = ch->fighting ) )
{
if ( ch->position == POS_FIGHTING )
ch->position = POS_STANDING;
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_FLEE ) )
{
if ( !IS_ARENA(ch) )
{
send_to_char(C_DEFAULT, "You failed! You lose 10 exps.\n\r", ch );
gain_exp( ch, -10 );
}
else
send_to_char(C_DEFAULT, "You failed!\n\r", ch);
return;
}
was_in = ch->in_room;
for ( attempt = 0; attempt < 6; attempt++ )
{
EXIT_DATA *pexit;
int door;
door = number_door( );
if ( ( pexit = was_in->exit[door] ) == 0
|| !pexit->to_room
|| IS_SET( pexit->exit_info, EX_CLOSED )
|| ( IS_NPC( ch )
&& ( IS_SET( pexit->to_room->room_flags, ROOM_NO_MOB )
|| ( IS_SET( ch->act, ACT_STAY_AREA )
&& pexit->to_room->area != ch->in_room->area ) ) ) )
continue;
move_char( ch, door, FALSE );
if ( ( now_in = ch->in_room ) == was_in )
continue;
ch->in_room = was_in;
act(C_DEFAULT, "$n has fled!", ch, NULL, NULL, TO_ROOM );
if ( IS_ARENA(ch) )
act(AT_RED, "$n has escaped! After $m!", ch, NULL, victim,
TO_VICT);
ch->in_room = now_in;
if ( !IS_NPC( ch ) )
{
if ( !IS_ARENA(ch) )
{
send_to_char(C_DEFAULT, "You flee from combat! You lose 25 exps.\n\r", ch );
gain_exp( ch, -25 );
}
else
send_to_char(C_DEFAULT, "You flee from combat!\n\r", ch);
}
if ( ch->fighting && IS_NPC( ch->fighting ) )
if ( IS_SET( ch->fighting->act, ACT_TRACK ) )
ch->fighting->hunting = ch;
stop_fighting( ch, TRUE );
return;
}
if ( !IS_ARENA(ch) )
{
send_to_char(C_DEFAULT, "You failed! You lose 10 exps.\n\r", ch );
gain_exp( ch, -10 );
}
else
send_to_char(C_DEFAULT, "You failed!\n\r", ch );
return;
}
void do_rescue( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
CHAR_DATA *fch;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_rescue ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the heroic acts to warriors.\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char(C_DEFAULT, "Rescue whom?\n\r", ch );
return;
}
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
if ( victim == ch )
{
send_to_char(C_DEFAULT, "What about fleeing instead?\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && IS_NPC( victim ) )
{
send_to_char(C_DEFAULT, "Doesn't need your help!\n\r", ch );
return;
}
if ( ch->fighting == victim )
{
send_to_char(C_DEFAULT, "Too late.\n\r", ch );
return;
}
if ( !( fch = victim->fighting ) )
{
send_to_char(C_DEFAULT, "That person is not fighting right now.\n\r", ch );
return;
}
if ( !is_same_group( ch, victim ) )
{
send_to_char(C_DEFAULT, "Why would you want to?\n\r", ch );
return;
}
if ( !check_blind ( ch ) )
return;
WAIT_STATE( ch, skill_table[gsn_rescue].beats );
if ( !IS_NPC( ch ) && number_percent( ) > ch->pcdata->learned[gsn_rescue] )
{
send_to_char(C_DEFAULT, "You fail the rescue.\n\r", ch );
return;
}
update_skpell( ch, gsn_rescue );
act(C_DEFAULT, "You rescue $N!", ch, NULL, victim, TO_CHAR );
act(C_DEFAULT, "$n rescues you!", ch, NULL, victim, TO_VICT );
act(C_DEFAULT, "$n rescues $N!", ch, NULL, victim, TO_NOTVICT );
stop_fighting( fch, FALSE );
set_fighting( fch, ch );
return;
}
void do_gouge( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_gouge ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to thieves.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_gouge].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_gouge] )
{
update_skpell( ch, gsn_gouge );
damage( ch, victim, number_range( 100, ch->level*5 ), gsn_gouge );
if ( number_percent( ) < 10 )
{
AFFECT_DATA af;
af.type = gsn_blindness;
af.duration = 5;
af.location = APPLY_HITROLL;
af.modifier = -10;
af.bitvector = AFF_BLIND;
affect_join( victim, &af );
act( AT_GREY, "$N is blinded!", ch, NULL, victim, TO_CHAR );
}
update_pos( victim );
}
else
damage( ch, victim, 0, gsn_gouge );
return;
}
void do_circle( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *obj;
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_circle ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to thieves.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !( obj = get_eq_char( ch, WEAR_WIELD ) )
|| ( obj->value[3] != 11 && obj->value[3] != 2 ) )
{
send_to_char(C_DEFAULT, "You need to wield a piercing or stabbing weapon.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_circle].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_circle] )
{
update_skpell( ch, gsn_circle );
damage( ch, victim, number_range( 400, ch->level*9 ), gsn_circle );
update_pos( victim );
}
else
damage( ch, victim, 0, gsn_circle );
return;
}
void do_kick( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_kick ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to warriors.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_kick].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_kick] )
{
damage( ch, victim, number_range( 100, ch->level*3 ), gsn_kick );
update_skpell( ch, gsn_kick );
}
else
damage( ch, victim, 0, gsn_kick );
return;
}
void do_high_kick( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_high_kick ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to warriors.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_high_kick].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_high_kick] )
{
damage( ch, victim, number_range( 150, ch->level*4 ), gsn_high_kick );
update_skpell( ch, gsn_high_kick );
}
else
damage( ch, victim, 0, gsn_high_kick );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's high kick connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's high kick hit $N's head!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 20, ch->level ), gsn_high_kick );
}
return;
}
void do_jump_kick( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_jump_kick ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to warriors.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_jump_kick].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_jump_kick] )
{
damage( ch, victim, number_range( 200, ch->level*4 ), gsn_jump_kick );
update_skpell( ch, gsn_jump_kick );
}
else
damage( ch, victim, 0, gsn_jump_kick );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's jump kick connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's jump kick hit $N's head!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 30, ch->level ), gsn_jump_kick );
}
return;
}
void do_spin_kick( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_spin_kick ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to warriors.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_spin_kick].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_spin_kick] )
{
damage( ch, victim, number_range( 250, ch->level*5 ), gsn_spin_kick );
update_skpell( ch, gsn_spin_kick );
}
else
damage( ch, victim, 0, gsn_spin_kick );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's spin kick connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's spin kick hit $N's head!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 40, ch->level ), gsn_spin_kick );
}
return;
}
void do_punch( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_punch ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to fighters.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_punch].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_punch] )
{
damage( ch, victim, number_range( 100, ch->level*3 ), gsn_punch );
update_skpell( ch, gsn_punch );
}
else
damage( ch, victim, 0, gsn_punch );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's punch connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's punch hit's home!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 1, ch->level ), gsn_punch );
}
return;
}
void do_jab_punch( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_jab_punch ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to fighters.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_jab_punch].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_jab_punch] )
{
damage( ch, victim, number_range( 125, ch->level*3 ), gsn_jab_punch );
update_skpell( ch, gsn_jab_punch );
}
else
damage( ch, victim, 0, gsn_jab_punch );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's jab connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's jab hit $N's head!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 1, ch->level ), gsn_jab_punch );
}
return;
}
void do_kidney_punch( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_kidney_punch ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to fighters.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_kidney_punch].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_kidney_punch] )
{
damage( ch, victim, number_range( 150, ch->level*3 ), gsn_kidney_punch );
update_skpell( ch, gsn_kidney_punch );
}
else
damage( ch, victim, 0, gsn_kidney_punch );
return;
}
void do_cross_punch( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_cross_punch ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to fighters.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_cross_punch].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_cross_punch] )
{
damage( ch, victim, number_range( 175, ch->level*3 ), gsn_cross_punch );
update_skpell( ch, gsn_cross_punch );
}
else
damage( ch, victim, 0, gsn_cross_punch );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's cross connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's cross hit $N's head!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 1, ch->level ), gsn_cross_punch );
}
return;
}
void do_roundhouse_punch( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_roundhouse_punch ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to fighters.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_roundhouse_punch].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_roundhouse_punch] )
{
damage( ch, victim, number_range( 200, ch->level*3 ), gsn_roundhouse_punch );
update_skpell( ch, gsn_roundhouse_punch );
}
else
damage( ch, victim, 0, gsn_roundhouse_punch );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's roundhouse connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's roundhouse hit $N's head!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 1, ch->level ), gsn_roundhouse_punch );
}
return;
}
void do_uppercut_punch( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int chance = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_uppercut_punch ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to fighters.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_uppercut_punch].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_uppercut_punch] )
{
damage( ch, victim, number_range( 225, ch->level*3 ), gsn_uppercut_punch );
update_skpell( ch, gsn_uppercut_punch );
}
else
damage( ch, victim, 0, gsn_uppercut_punch );
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room )
return;
if ( !IS_NPC( ch ) )
chance = ch->pcdata->mod_str + ( ch->level - victim->level ) + ch->pcdata->perm_str;
if ( ( number_percent( ) < chance ) || IS_NPC( ch ) )
{
act( AT_RED, "You hear a crunch as you connect with $N's head.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n's uppercut connects firmly with your head!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n's uppercut hit $N's head!", ch, NULL, victim, TO_ROOM );
damage( ch, victim, number_range( 1, ch->level ), gsn_uppercut_punch );
}
return;
}
void do_flury( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int count = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_punch ) )
{
send_to_char(C_DEFAULT,
"You'd better leave the martial arts to fighters.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
if ( ( get_eq_char( ch, WEAR_WIELD ) ) || ( get_eq_char( ch, WEAR_WIELD_2 ) ) ||
( get_eq_char( ch, WEAR_HOLD ) ) )
{
send_to_char(C_DEFAULT, "You cannot begin such a flury while your hands are full!\n\r", ch);
return;
}
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_punch].beats );
act( AT_RED, "You throw a flury of punches and kicks at $N!", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n throws a flury of punches and kicks at you!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "$n throws a flury of punches and kicks at $N!", ch, NULL, victim, TO_ROOM );
if ( can_use_skpell( ch, gsn_punch ) && number_percent( ) < 10 )
{
do_punch( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_kick ) && number_percent( ) < 10 )
{
do_kick( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_jab_punch ) && number_percent( ) < 10 )
{
do_jab_punch( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_kidney_punch ) && number_percent( ) < 10 )
{
do_kidney_punch( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_cross_punch ) && number_percent( ) < 10 )
{
do_cross_punch( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_high_kick ) && number_percent( ) < 10 )
{
do_high_kick( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_roundhouse_punch ) && number_percent( ) < 10 )
{
do_roundhouse_punch( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_jump_kick ) && number_percent( ) < 10 )
{
do_jump_kick( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_uppercut_punch ) && number_percent( ) < 10 )
{
do_uppercut_punch( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
if ( can_use_skpell( ch, gsn_spin_kick ) && number_percent( ) < 10 )
{
do_spin_kick( ch, arg );
count++;
}
if ( !victim || victim->position == POS_DEAD || !victim->in_room
|| victim->in_room != ch->in_room || count > 2 )
return;
/* nothing hit */
if ( count == 0 )
{
act( AT_RED, "But none of your attacks hit $N!", ch, NULL, victim, TO_CHAR );
act( AT_RED, "But none of $n attacks hit you!", ch, NULL, victim, TO_VICT );
act( C_DEFAULT, "But none of $n attacks hit $N!", ch, NULL, victim, TO_ROOM );
}
return;
}
void do_feed( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !is_class( ch, CLASS_VAMPIRE ) )
{
send_to_char( AT_WHITE, "You may not feed on the living.\n\r", ch );
return;
}
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_feed ) )
{
send_to_char(AT_RED,
"You are yet to young to feast on the blood of the living.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(AT_WHITE, "You aren't fighting anyone.\n\r", ch );
return;
}
/*
if ( ch->level < L_APP && ch->class == CLASS_VAMPIRE )
if ( !IS_SET( ch->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 6 && time_info.hour < 18 )
{
send_to_char(AT_RED, "You may not feed during the cursed day.\n\r", ch );
return;
}
}
*/
if ( !check_blind( ch ) )
return;
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(AT_WHITE, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_feed].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_feed] )
{
int amnt;
update_skpell( ch, gsn_feed );
amnt = number_range( 5, 20 );
if ( ( ch->bp + amnt ) > MAX_BP(ch))
ch->bp = MAX_BP(ch);
else
ch->bp += amnt;
damage( ch, victim, number_range( 1, ch->level ), gsn_feed );
}
else
damage( ch, victim, 0, gsn_feed );
return;
}
void do_disarm( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *obj;
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
int percent;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_disarm ) )
{
send_to_char(C_DEFAULT, "You don't know how to disarm opponents.\n\r", ch );
return;
}
if ( ( !get_eq_char( ch, WEAR_WIELD ) )
&& ( !get_eq_char( ch, WEAR_WIELD_2 ) )
&& !is_class( ch, CLASS_WEREWOLF ) )
{
send_to_char(C_DEFAULT, "You must wield a weapon to disarm.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( !check_blind( ch ) )
return;
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
if ( victim->fighting != ch && ch->fighting != victim )
{
act(C_DEFAULT, "$E is not fighting you!", ch, NULL, victim, TO_CHAR );
return;
}
if ( !( obj = get_eq_char( victim, WEAR_WIELD ) ) )
{
if ( !( obj = get_eq_char( victim, WEAR_WIELD_2 ) ) )
{
send_to_char(C_DEFAULT, "Your opponent is not wielding a weapon.\n\r", ch );
return;
}
}
if ( number_percent( ) < victim->antidisarm )
{
send_to_char( C_DEFAULT, "You failed.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_disarm].beats );
percent = number_percent( ) + victim->level - ch->level;
if ( ( IS_NPC( ch ) && percent < 20 ) || ( ( !IS_NPC(ch) ) &&
( percent < ch->pcdata->learned[gsn_disarm] * 2 / 3 ) ) )
{
disarm( ch, victim );
update_skpell( ch, gsn_disarm );
}
else
send_to_char(C_DEFAULT, "You failed.\n\r", ch );
return;
}
void do_sla( CHAR_DATA *ch, char *argument )
{
send_to_char(C_DEFAULT, "If you want to SLAY, spell it out.\n\r", ch );
return;
}
void do_slay( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
char buf [ MAX_STRING_LENGTH ];
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char(C_DEFAULT, "Slay whom?\n\r", ch );
return;
}
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
/* if ( ch == victim )
{
send_to_char(C_DEFAULT, "Suicide is a mortal sin.\n\r", ch );
return;
}*/
if ( ( !IS_NPC( victim ) && victim->level >= ch->level && victim != ch ) ||
(IS_NPC( ch ) && !IS_NPC( victim )) )
{
send_to_char(C_DEFAULT, "You failed.\n\r", ch );
return;
}
/*
act(C_DEFAULT, "You slay $M in cold blood!", ch, NULL, victim, TO_CHAR );
act(C_DEFAULT, "$n slays you in cold blood!", ch, NULL, victim, TO_VICT );
act(C_DEFAULT, "$n slays $N in cold blood!", ch, NULL, victim, TO_NOTVICT );
*/
sprintf( buf, "You %s.",
( ch->pcdata && ch->pcdata->slayusee[0] != '\0' )
? ch->pcdata->slayusee : "slay $N in cold blood." );
act( AT_RED, buf, ch, NULL, victim, TO_CHAR );
sprintf( buf, "%s %s.", ch->name,
( ch->pcdata && ch->pcdata->slayvict[0] != '\0' )
? ch->pcdata->slayvict : "slays you in cold blood!" );
act(AT_RED, buf, ch, NULL, victim, TO_VICT );
sprintf( buf, "%s %s.", ch->name,
( ch->pcdata && ch->pcdata->slayroom[0] != '\0' )
? ch->pcdata->slayroom : "slays $N in cold blood!");
act(AT_RED, buf, ch, NULL, victim, TO_NOTVICT );
sprintf( log_buf, "%s slays %s at %d.\n\r", ch->name, victim->name,
victim->in_room->vnum );
log_string( log_buf, CHANNEL_LOG, ch->level - 1 );
if ( !IS_NPC( victim ) )
wiznet( log_buf,ch, NULL, WIZ_DEATHS, 0, 0 );
raw_kill( ch, victim );
return;
}
int per_type( CHAR_DATA *ch, OBJ_DATA *Obj )
{
switch ( Obj->item_type )
{
case ITEM_WEAPON:
return number_range( 5, ch->level + 5 );
case ITEM_STAFF:
return number_range( 3, ch->level + 3 );
case ITEM_WAND:
return number_range( 2, ch->level + 2 );
default:
return number_range( 1, ch->level );
}
return number_range( 1, ch->level );
}
void do_throw( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
ROOM_INDEX_DATA *to_room;
ROOM_INDEX_DATA *in_room;
OBJ_DATA *Obj;
EXIT_DATA *pexit;
int dir = 0;
int dist = 0;
int MAX_DIST = 2;
extern char *dir_noun [];
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
if ( arg1[0] == '\0' )
{
send_to_char( C_DEFAULT, "Throw what item?\n\r", ch );
return;
}
if ( ( Obj = get_obj_wear( ch, arg1 ) ) == NULL )
{
send_to_char( C_DEFAULT,
"You are not wearing, wielding, or holding that item.\n\r",
ch );
return;
}
if ( Obj->wear_loc != WEAR_WIELD && Obj->wear_loc != WEAR_WIELD_2 &&
Obj->wear_loc != WEAR_HOLD )
{
send_to_char( C_DEFAULT,
"You are not wielding or holding that item.\n\r", ch );
return;
}
if ( IS_SET( Obj->extra_flags, ITEM_NOREMOVE ) || IS_SET( Obj->extra_flags,
ITEM_NODROP ) )
{
send_to_char( C_DEFAULT, "You can't let go of it!\n\r", ch );
return;
}
in_room = ch->in_room;
to_room = ch->in_room;
if ( ( victim = ch->fighting ) == NULL )
{
if ( arg2[0] == '\0' )
{
send_to_char( C_DEFAULT, "Throw it at who?\n\r", ch );
return;
}
if ( arg3[0] == '\0' )
{
if ( ( victim = get_char_room( ch, arg2 ) ) == NULL )
{
send_to_char( C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
}
else
{
if ( get_curr_str( ch ) >= 20 )
{
MAX_DIST = 3;
if ( get_curr_str( ch ) == 25 )
MAX_DIST = 4;
}
for ( dir = 0; dir < 6; dir++ )
if ( arg2[0] == dir_name[dir][0] && !str_prefix( arg2,
dir_name[dir] ) )
break;
if ( dir == 6 )
{
send_to_char( C_DEFAULT, "Throw in which direction?\n\r", ch );
return;
}
if ( ( pexit = to_room->exit[dir] ) == NULL ||
( to_room = pexit->to_room ) == NULL )
{
send_to_char( C_DEFAULT, "You cannot throw in that direction.\n\r",
ch );
return;
}
if ( IS_SET( pexit->exit_info, EX_CLOSED ) )
{
send_to_char( C_DEFAULT, "You cannot throw through a door.\n\r", ch );
return;
}
for ( dist = 1; dist <= MAX_DIST; dist++ )
{
char_from_room( ch );
char_to_room( ch, to_room );
if ( ( victim = get_char_room( ch, arg3 ) ) != NULL )
break;
if ( ( pexit = to_room->exit[dir] ) == NULL ||
( to_room = pexit->to_room ) == NULL ||
IS_SET( pexit->exit_info, EX_CLOSED ) )
{
sprintf( buf, "A $p flys in from $T and hits the %s wall.",
dir_name[dir] );
act( AT_WHITE, buf, ch, Obj, dir_noun[rev_dir[dir]], TO_ROOM );
sprintf( buf, "You throw your $p %d room%s $T, where it hits a wall.",
dist, dist > 1 ? "s" : "" );
act( AT_WHITE, buf, ch, Obj, dir_name[dir], TO_CHAR );
char_from_room( ch );
char_to_room( ch, in_room );
oprog_throw_trigger( Obj, ch );
unequip_char( ch, Obj );
obj_from_char( Obj );
obj_to_room( Obj, to_room );
return;
}
}
if ( victim == NULL )
{
act( AT_WHITE,
"A $p flies in from $T and falls harmlessly to the ground.",
ch, Obj, dir_noun[rev_dir[dir]], TO_ROOM );
sprintf( buf,
"Your $p falls harmlessly to the ground %d room%s $T of here.",
dist, dist > 1 ? "s" : "" );
act( AT_WHITE, buf, ch, Obj, dir_name[dir], TO_CHAR );
char_from_room( ch );
char_to_room( ch, in_room );
oprog_throw_trigger( Obj, ch );
unequip_char( ch, Obj );
obj_from_char( Obj );
obj_to_room( Obj, to_room );
return;
}
}
if ( dist > 0 )
{
char_from_room( ch );
char_to_room( ch, in_room );
act( AT_WHITE, "A $p flys in from $T and hits $n!", victim, Obj,
dir_noun[rev_dir[dir]], TO_NOTVICT );
act( AT_WHITE, "A $p flys in from $T and hits you!", victim, Obj,
dir_noun[rev_dir[dir]], TO_CHAR );
sprintf( buf, "Your $p flew %d rooms %s and hit $N!", dist,
dir_name[dir] );
act( AT_WHITE, buf, ch, Obj, victim, TO_CHAR );
oprog_throw_trigger( Obj, ch );
unequip_char( ch, Obj );
obj_from_char( Obj );
obj_to_room( Obj, to_room );
damage( ch, victim, per_type( ch, Obj ), gsn_throw );
update_skpell( ch, gsn_throw ); /* Throw not given to any class though */
if ( IS_NPC( victim ) )
{
if ( victim->level > 3 )
victim->hunting = ch;
}
return;
}
}
unequip_char( ch, Obj );
obj_from_char( Obj );
obj_to_room( Obj, to_room );
act( AT_WHITE, "$n threw a $p at $N!", ch, Obj, victim, TO_ROOM );
act( AT_WHITE, "You throw your $p at $N.", ch, Obj, victim, TO_CHAR );
oprog_throw_trigger( Obj, ch );
damage( ch, victim, per_type( ch, Obj ), gsn_throw );
multi_hit( victim, ch, TYPE_UNDEFINED );
return;
}
/*
void do_track( CHAR_DATA *ch, char *argument )
{
ROOM_INDEX_DATA *room[30];
ROOM_INDEX_DATA *to_room;
ROOM_INDEX_DATA *in_room;
EXIT_DATA *pexit[30];
char arg[MAX_STRING_LENGTH];
int vnums[30];
int dist[30];
int sdir[30];
int dir[6];
int nsdir;
nsdir = 1;
argument = one_argument( argument, arg );
if ( is_number( arg ) || arg[0] == \0' )
{
send_to_char( AT_WHITE, "Track what?\n\r", ch );
return;
}
in_room = ch->in_room;
to_room = ch->in_room;
for ( dir = 0; dir != -1; dir++ )
{
if ( !( pexit[nsdir] = ch->in_room->exit[dir] )
|| ( !( to_room = pexit[nsdir]->to_room ) ) )
{
if ( dir == 6 )
dir = -1;
continue;
char_from_room( ch );
char_to_room( ch, to_room );
if ( get_char_room( ch, arg ) )
break;
}
}
if ( dir != -1 )
{
sprintf( log_buf, "You sense the trail of %s to the %s.\n\r",
arg, dir_name[dir] );
send_to_char( AT_WHITE, log_buf, ch );
char_from_room( ch );
char_to_room( ch, in_room );
}
if ( dir == -1 )
{
sprintf( log_buf, "You can't sense any %s from here.\n\r", arg );
send_to_char( AT_WHITE, log_buf, ch );
return;
}
return;
}
*/
void do_drain_life(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *victim;
int dam;
if(!IS_NPC(ch)
&& !can_use_skpell( ch, gsn_drain_life ) )
{
send_to_char(C_DEFAULT, "You failed.\n\r", ch);
return;
}
if(argument[0] != '\0')
{
if(!(victim = get_char_room(ch, argument)))
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch);
return;
}
}
else
{
if(!(victim = ch->fighting))
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch);
return;
}
}
if(is_safe(ch, victim))
return;
WAIT_STATE(ch, skill_table[gsn_drain_life].beats);
/* 3xlevel + 1dlevel*/
if(IS_NPC(ch) || number_percent() < ch->pcdata->learned[gsn_drain_life])
{
dam = ch->level + number_range(ch->level / 2, ch->level);
damage(ch, victim, dam, gsn_drain_life);
update_skpell(ch, gsn_drain_life);
ch->hit = UMIN(ch->hit + dam/2, MAX_HIT(ch));
}
else
{
send_to_char(C_DEFAULT, "You failed.", ch);
damage(ch, victim, 0, gsn_drain_life);
}
return;
}
void do_mental_drain(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *victim;
int dam;
int drain;
int dmana;
if(!IS_NPC(ch)
&& !can_use_skpell( ch, gsn_mental_drain ) )
{
send_to_char(C_DEFAULT, "You failed.\n\r", ch);
return;
}
if(argument[0] != '\0')
{
if(!(victim = get_char_room(ch, argument)))
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch);
return;
}
}
else
{
if(!(victim = ch->fighting))
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch);
return;
}
}
if(is_safe(ch, victim))
return;
if ( ch->race == RACE_ILLITHID )
WAIT_STATE(ch, skill_table[gsn_mental_drain].beats/3);
else
WAIT_STATE(ch, skill_table[gsn_mental_drain].beats);
/* 3xlevel + 1d100*/
if(IS_NPC(ch) || number_percent() < ch->pcdata->learned[gsn_mental_drain])
{
dam = number_range(ch->level / 5, ch->level);
/* drain = 2 * ch->level + number_range(ch->level / 4, ch->level * 2);*/
dmana = drain = ch->level + number_range(ch->level / 4, ch->level);
if ( ch->race == RACE_ILLITHID )
{
dam *= 1.5;
dmana = drain *= 2.5;
}
damage(ch, victim, dam, gsn_mental_drain);
update_skpell(ch, gsn_mental_drain);
/* ch->hit = UMIN(ch->hit + dam/4, MAX_HIT(ch));*/
if ( !IS_NPC(victim) )
{
dmana = UMAX(victim->mana - dmana, 0 );
drain = UMAX(victim->move - drain, 0 );
victim->mana -= dmana;
victim->move -= drain;
}
ch->mana = UMIN(ch->mana + dmana / 2, MAX_MANA(ch));
ch->move = UMIN(ch->move + drain / 2, MAX_MOVE(ch));
}
else
{
send_to_char(C_DEFAULT, "You failed.", ch);
damage(ch, victim, 0, gsn_mental_drain);
}
return;
}
void do_stun( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
if (!IS_NPC(ch) && !can_use_skpell( ch, gsn_stun ) )
{
send_to_char(C_DEFAULT, "You failed.\n\r", ch );
return;
}
if ( !(victim = ch->fighting) )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r",ch);
return;
}
if ( victim->position == POS_STUNNED || IS_STUNNED( ch, STUN_TO_STUN ) )
return;
if ( ( IS_NPC(ch) || number_percent() < ch->pcdata->learned[gsn_stun] ) &&
number_percent() < (ch->level * 75) / victim->level )
{
STUN_CHAR( ch, 10, STUN_TO_STUN );
STUN_CHAR( victim, 3, STUN_TOTAL );
victim->position = POS_STUNNED;
act( AT_WHITE, "You stun $N!", ch, NULL, victim, TO_CHAR );
act( AT_WHITE, "$n stuns $N!", ch, NULL, victim, TO_NOTVICT );
act( AT_WHITE, "$n stuns you!", ch, NULL, victim, TO_VICT );
update_skpell(ch, gsn_stun);
return;
}
send_to_char(C_DEFAULT, "You failed.\n\r", ch );
return;
}
void do_berserk( CHAR_DATA *ch, char *argument )
{
AFFECT_DATA af;
if ( !ch->fighting )
return;
if ( !IS_NPC(ch) && ch->pcdata->learned[gsn_berserk] < number_percent() )
{
send_to_char(C_DEFAULT, "You failed.\n\r",ch);
return;
}
af.type = gsn_berserk;
af.level = ch->level;
af.duration = ch->level / 10;
af.bitvector = AFF_BERSERK;
af.location = APPLY_DAMROLL;
af.modifier = IS_NPC(ch) ? ch->level / 2 : ch->damroll * 2 / 3;
affect_to_char2(ch, &af);
af.location = APPLY_HITROLL;
af.modifier = IS_NPC(ch) ? ch->level / 2 : ch->hitroll * 2 / 3;
affect_to_char2(ch, &af);
af.location = APPLY_AC;
af.modifier = ch->level * -2;
affect_to_char2(ch, &af);
send_to_char(AT_WHITE, "You suddenly go berserk.\n\r",ch);
act(AT_WHITE, "$n suddenly goes berserk!", ch, NULL, NULL, TO_ROOM );
update_skpell( ch, gsn_berserk );
return;
}
void do_soulstrike( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim = ch->fighting;
int dam;
if ( !victim )
{
send_to_char( AT_WHITE, "You aren't fighting anyone!\n\r", ch );
return;
}
if (!IS_NPC(ch) && ch->pcdata->learned[gsn_soulstrike] < number_percent( ))
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
if ( IS_NEUTRAL(ch) )
{
send_to_char(AT_RED, "Nothing happened.\n\r", ch );
return;
}
dam = number_range( ch->level / 3, (ch->level * 2) / 3 );
if ( ch->hit < dam * 2 )
{
send_to_char(AT_WHITE, "You do not have the strength.\n\r", ch );
return;
}
/* Don't need a check for update_pos, because of the previous check. */
ch->hit -= dam;
dam = number_range( dam * 3, dam * 5 );
WAIT_STATE(ch, 2*PULSE_VIOLENCE);
if ( IS_EVIL(ch) )
{
send_to_char(AT_RED, "Your soul recoils!\n\r", ch);
damage(ch, ch, dam, gsn_soulstrike);
return;
}
act( AT_BLUE, "Your soul strikes deep into $N.", ch, NULL, victim, TO_CHAR );
act( AT_BLUE, "$n's soul strikes deep into you.", ch, NULL, victim, TO_VICT );
act( AT_BLUE, "$n's soul strikes deep into $N.", ch, NULL, victim, TO_NOTVICT );
damage(ch, victim, dam, gsn_soulstrike);
update_skpell( ch, gsn_soulstrike );
return;
}
void do_multiburst( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim = ch->fighting;
char arg1 [ MAX_INPUT_LENGTH ];
char arg2 [ MAX_INPUT_LENGTH ];
int sn1;
int sn2;
bool legal1 = FALSE;
bool legal2 = FALSE;
int mana = 0;
if ( IS_NPC( ch ) )
return;
if ( !can_use_skpell( ch, gsn_multiburst ) )
{
send_to_char( C_DEFAULT, "You're not enough of a mage to do multibursts.\n\r" , ch );
return;
}
if ( IS_STUNNED( ch, STUN_MAGIC ) )
{
send_to_char( AT_LBLUE, "You are too stunned to multiburst.\n\r", ch );
return;
}
if ( ch->pcdata->learned[gsn_multiburst] < number_percent( ) )
{
send_to_char( C_DEFAULT, "You fail your multiburst.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char( C_DEFAULT, "You aren't fighting.\n\r", ch );
return;
}
if ( IS_AFFECTED( ch, AFF_MUTE ))
{
send_to_char(AT_WHITE, "You have been silenced.\n\r", ch);
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
sn1 = skill_lookup( arg1 );
sn2 = skill_lookup( arg2 );
if ( sn1 != -1
&& can_use_skpell( ch, sn1 )
&& skill_table[sn1].target != TAR_CHAR_SELF
&& (*skill_table[sn1].spell_fun) != (*spell_null) )
legal1 = TRUE;
if ( sn2 != -1
&& can_use_skpell( ch, sn2 )
&& skill_table[sn2].target != TAR_CHAR_SELF
&& (*skill_table[sn2].spell_fun) != (*spell_null) )
legal2 = TRUE;
if ( !legal1 && !legal2 )
{
WAIT_STATE( ch, skill_table[gsn_multiburst].beats );
send_to_char( C_DEFAULT, "Your multiburst fails.\n\r", ch );
return;
}
if ( legal1 )
{
mana += SPELL_COST( ch, sn1 );
mana += SPELL_COST( ch, sn1 ) * 0.2;
}
if ( legal2 )
{
mana += SPELL_COST( ch, sn2 );
mana += SPELL_COST( ch, sn2 ) * 0.2;
}
mana += mana * 0.1;
if ( ch->mana < mana && ch->level < LEVEL_IMMORTAL )
{
WAIT_STATE( ch, skill_table[gsn_multiburst].beats );
send_to_char( C_DEFAULT, "You don't have enough mana to multiburst these spells.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_multiburst].beats );
send_to_char( AT_RED, "You release a burst of energy!\n\r", ch );
act( AT_RED, "$n releases a burst of energy.", ch, NULL, NULL, TO_ROOM );
update_skpell( ch, gsn_multiburst );
if ( legal1 )
(*skill_table[sn1].spell_fun) ( sn1,
URANGE( 1, ch->level, LEVEL_HERO ),
ch, victim );
if ( victim->position != POS_DEAD && ch->in_room == victim->in_room )
{
if ( legal2 )
(*skill_table[sn2].spell_fun) ( sn2,
URANGE( 1, ch->level, LEVEL_HERO ),
ch, victim );
}
if ( ch->level < LEVEL_IMMORTAL )
MT( ch ) -= mana;
return;
}
void do_rage( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *wield;
OBJ_DATA *wield2;
char buf [ MAX_INPUT_LENGTH ];
AFFECT_DATA af;
if ( IS_AFFECTED2( ch, AFF_RAGE ) )
return;
if ( !can_use_skpell( ch, gsn_rage ) )
{
send_to_char( C_DEFAULT, "You are not enough of a beast.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_rage] < number_percent( ) )
{
send_to_char( C_DEFAULT, "You cannot summon enough anger.\n\r", ch );
return;
}
wield = get_eq_char( ch, WEAR_WIELD );
wield2 = get_eq_char( ch , WEAR_WIELD_2 );
if ( wield || wield2 )
{
sprintf( buf,
"You become enraged and toss your weapon%s to the ground.\n\r",
( wield && wield2 ) ? "s" : "" );
send_to_char( AT_RED, buf, ch );
sprintf( buf,
"$n tosses his weapon%s to the ground in a fit of rage.",
( wield && wield2 ) ? "s" : "" );
act( C_DEFAULT, buf, ch, NULL, NULL, TO_ROOM );
if ( wield )
{
obj_from_char( wield );
obj_to_room( wield, ch->in_room );
}
if ( wield2 )
{
obj_from_char( wield2 );
obj_to_room( wield2, ch->in_room );
}
}
else
{
send_to_char( AT_RED,
"You become enraged and surge with power.\n\r", ch );
}
update_skpell( ch, gsn_rage );
af.type = gsn_rage;
af.level = ch->level;
af.duration = ch->level * 0.4;
af.location = APPLY_STR;
af.modifier = 5;
af.bitvector = AFF_RAGE;
affect_to_char2( ch, &af );
af.location = APPLY_HITROLL;
af.modifier = ch->level;
affect_to_char2( ch, &af );
af.location = APPLY_DAMROLL;
af.modifier = ch->level;
affect_to_char2( ch, &af );
return;
}
void do_challenge(CHAR_DATA *ch, char *argument)
{
int award;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int rvnum = ch->in_room->vnum;
#ifdef NEW_MONEY
MONEY_DATA amount;
#endif
if ( IS_NPC(ch) )
{
send_to_char( C_DEFAULT, "NPC's can't fight in the arena.\n\r", ch );
return;
}
if ( rvnum == ROOM_VNUM_HELL
|| rvnum == ROOM_VNUM_RJAIL )
{
send_to_char( C_DEFAULT, "Nice try, but get out the real way.\n\r", ch );
return;
}
if ( arena.fch && arena.sch )
{
send_to_char( C_DEFAULT, "There are already two people fighting in the"
" arena.\n\r", ch );
return;
}
if ( arena.cch )
{
sprintf(arg1, "%s is offering a challenge. Type accept to accept it.\n\r",
arena.cch->name);
send_to_char( C_DEFAULT, arg1, ch );
return;
}
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
if ( (is_number(arg1) && (award = atoi(arg1)) < 1 )
|| ( !is_number(arg1) && !is_number(arg2) )
|| ( is_number(arg2) && (award = atoi(arg2)) < 1 ) )
{
send_to_char( C_DEFAULT, "Syntax: challenge [player] <award>\n\r", ch );
send_to_char( C_DEFAULT, " Player is the optional name of a specific person to challenge.\n\r", ch);
send_to_char( C_DEFAULT, " Award is at least 1 gold coins.\n\r", ch );
return;
}
else if ( (award = atoi(arg2)) )
{
DESCRIPTOR_DATA *d;
bool found = FALSE;
for ( d = descriptor_list; d; d = d->next )
{
if ( d->connected == CON_PLAYING
&& is_name( NULL, arg1, d->character->name )
&& d->character && ch )
{
found = TRUE;
arena.och = d->character;
break;
}
}
if ( !found )
{
send_to_char( C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
}
else
award = atoi(arg1);
#ifdef NEW_MONEY
/* Convert and compare copper values: */
if ( award*100 > ( ch->money.gold*C_PER_G + ch->money.silver*S_PER_G +
ch->money.copper ) )
/* if ( award > ( ch->money.gold + (ch->money.silver/SILVER_PER_GOLD) +
(ch->money.copper/COPPER_PER_GOLD) ) ) */
{
#else
if ( award > ch->gold )
{
#endif
send_to_char( C_DEFAULT, "You can't afford that.\n\r", ch );
arena.och = NULL;
return;
}
if ( !get_room_index(ROOM_ARENA_ENTER_F) ||
!get_room_index(ROOM_ARENA_ENTER_S) )
{
send_to_char( C_DEFAULT, "An error has occured. Please inform an Immortal.\n\r", ch );
return;
}
arena.cch = ch;
arena.count = 0;
arena.award = award;
#ifdef NEW_MONEY
amount.silver = amount.copper = 0;
amount.gold = award;
spend_money( &ch->money, &amount );
#else
ch->gold -= award;
#endif
if ( arena.och )
sprintf(log_buf, "&C%s &cchallenges &C%s &cto a fight in the arena for &W%d &cgold coins.",
ch->name, arena.och->name, award );
else
sprintf(log_buf, "&C%s &coffers a challenge in the arena for &W%d &cgold coins.",
ch->name, award);
/* wiznet(log_buf, NULL, NULL, WIZ_DEATHS, 0, 0); */
log_string(log_buf, CHANNEL_LOG, -1);
challenge(log_buf, 0, 0);
send_to_char( C_DEFAULT, "Your challenge has been offered.\n\r", ch );
return;
}
void do_accept(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *cch, *och;
int rvnum = ch->in_room->vnum;
#ifdef NEW_MONEY
MONEY_DATA amount;
#endif
if ( IS_NPC(ch) )
{
send_to_char( C_DEFAULT, "NPC's may not fight in the arena.\n\r", ch );
return;
}
if ( !(cch = arena.cch) )
{
send_to_char( C_DEFAULT, "There is no challenge being offered.\n\r", ch );
return;
}
if ( rvnum == ROOM_VNUM_HELL
|| rvnum == ROOM_VNUM_RJAIL )
{
send_to_char( C_DEFAULT, "Nice try, but get out the real way.\n\r", ch );
return;
}
if ( ch->fighting )
{
send_to_char( C_DEFAULT, "You are already fighting.\n\r", ch );
return;
}
if ( ch == cch )
{
send_to_char( C_DEFAULT, "You can't accept your own challenge!\n\r", ch );
return;
}
if ( ( och = arena.och ) && och != ch )
{
send_to_char( C_DEFAULT, "You are not the one being challenged.\n\r", ch );
return;
}
#ifdef NEW_MONEY
if ( ( ch->money.gold*C_PER_G + ch->money.silver*S_PER_G +
ch->money.copper ) < arena.award*100 )
/* if ( (ch->money.gold + (ch->money.silver/SILVER_PER_GOLD) +
(ch->money.copper/COPPER_PER_GOLD) ) < arena.award ) */
{
send_to_char( C_DEFAULT, "You cannot afford that.\n\r", ch );
return;
}
amount.silver = amount.copper = 0;
amount.gold = arena.award;
spend_money( &ch->money, &amount );
#else
if ( ch->gold < arena.award )
{
send_to_char( C_DEFAULT, "You cannot afford that.\n\r", ch );
return;
}
ch->gold -= arena.award;
#endif
arena.award *= 2;
arena.fch = cch;
arena.sch = ch;
arena.cch = NULL;
arena.och = NULL;
send_to_char( C_DEFAULT, "Your challenge has been accepted.\n\r", cch );
stop_fighting(cch, FALSE);
act( AT_LBLUE, "A pentagram forms around $n and he slowly dissipates.",
cch, NULL, NULL, TO_ROOM );
char_from_room(cch);
char_to_room(cch, get_room_index(ROOM_ARENA_ENTER_F));
do_look(cch, "auto");
act( AT_LBLUE, "A pentagram forms around $n and he slowly dissipates.",
ch, NULL, NULL, TO_ROOM );
char_from_room(ch);
char_to_room(ch, get_room_index(ROOM_ARENA_ENTER_S));
do_look(ch, "auto");
sprintf(log_buf, "&C%s &chas accepted &C%s&c's challenge.",
ch->name, cch->name);
/* wiznet(log_buf, NULL, NULL, WIZ_DEATHS, 0, 0); */
log_string(log_buf, CHANNEL_LOG, -1);
challenge(log_buf, 0, 0);
send_to_char(AT_RED, "Be prepared.\n\r", ch);
send_to_char(AT_RED, "Be prepared.\n\r", cch);
return;
}
void do_bite(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *victim;
int dam;
float wait_mod;
if(!IS_NPC(ch)
&& !can_use_skpell( ch, gsn_bite ) )
{
send_to_char(C_DEFAULT, "You gnash your teeth wildly.\n\r", ch);
return;
}
if(argument[0] != '\0')
{
if(!(victim = get_char_room(ch, argument)))
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch);
return;
}
}
else
{
if(!(victim = ch->fighting))
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch);
return;
}
}
if(is_safe(ch, victim))
return;
if ( ch->level < 25 )
wait_mod = 0.5;
else if ( ch->level < 40 )
wait_mod = 1;
else if ( ch->level < 60 )
wait_mod = 1.5;
else if ( ch->level < 80 )
wait_mod = 2;
else
wait_mod = 3;
WAIT_STATE(ch, skill_table[gsn_bite].beats / wait_mod);
if(IS_NPC(ch) || number_percent() < ch->pcdata->learned[gsn_bite])
{
dam = ch->level + number_range(ch->level, ch->level * 5);
damage(ch, victim, dam, gsn_bite);
update_skpell(ch, gsn_bite);
}
else
{
send_to_char(C_DEFAULT, "You failed.", ch);
damage(ch, victim, 0, gsn_bite);
}
return;
}
void do_rush( CHAR_DATA *ch, char *argument )
{
AFFECT_DATA af;
if ( IS_NPC( ch ) )
return;
if ( IS_AFFECTED2( ch, AFF_RUSH ) )
return;
if ( !can_use_skpell( ch, gsn_rush ) )
{
send_to_char( C_DEFAULT, "You can't pump yourself up enough.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_rush].beats );
if ( ch->pcdata->learned[gsn_rush] < number_percent( ) )
{
send_to_char( C_DEFAULT, "You failed.\n\r", ch );
return;
}
send_to_char( AT_RED, "You pump yourself up and make the adrenaline flow.\n\r", ch );
act( AT_WHITE, "$n seems to be pumped up.", ch, NULL, NULL, TO_ROOM );
af.type = gsn_rush;
af.level = ch->level;
af.duration = ch->level / 4;
af.location = APPLY_DEX;
af.modifier = -2;
af.bitvector = AFF_RUSH;
affect_to_char2( ch, &af );
update_skpell( ch, gsn_rush );
return;
}
void do_howl_of_fear(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *victim;
if(!IS_NPC(ch)
&& is_class( ch, gsn_howlfear ) )
{
send_to_char(C_DEFAULT, "You failed.\n\r", ch);
return;
}
if ( IS_NPC( ch ) )
return;
if(argument[0] != '\0')
{
if(!(victim = get_char_room(ch, argument)))
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch);
return;
}
}
else
{
if(!(victim = ch->fighting))
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch);
return;
}
}
if(is_safe(ch, victim))
return;
if (is_affected(victim, gsn_howlfear) )
{
act( AT_RED, "$N is already scared witless.", ch, NULL, victim, TO_CHAR );
return;
}
WAIT_STATE(ch, skill_table[gsn_howlfear].beats);
if(number_percent() < ch->pcdata->learned[gsn_howlfear])
{
AFFECT_DATA af;
af.type = gsn_howlfear;
af.level = ch->level;
af.duration = 10;
af.location = APPLY_DAMROLL;
af.modifier = 0 - ch->level / 2;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = 0 - ch->level / 2;
affect_to_char( victim, &af );
af.level = ch->level;
af.duration = 10;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_ANTI_FLEE;
affect_to_char( victim, &af );
act( AT_RED, "Your chilling howl instills fear in $N.",
ch, NULL, victim, TO_CHAR );
act( AT_RED, "You cringe in terror at the sound of $n's howl.",
ch, NULL, victim, TO_VICT );
act( AT_RED, "$n howls and $N cringes back in terror.",
ch, NULL, victim, TO_NOTVICT );
if ( !victim->fighting )
set_fighting( victim, ch );
}
update_skpell( ch, gsn_howlfear );
return;
}
void do_frenzy( CHAR_DATA *ch, char *argument )
{
AFFECT_DATA af;
if ( IS_AFFECTED2( ch, AFF_BERSERK ) )
return;
if ( !ch->fighting )
return;
if ( !IS_NPC(ch) && ch->pcdata->learned[gsn_frenzy] < number_percent() )
{
send_to_char(C_DEFAULT, "You failed.\n\r",ch);
return;
}
af.type = gsn_frenzy;
af.level = ch->level;
af.duration = ch->level / 10;
af.bitvector = AFF_BERSERK;
af.location = APPLY_DAMROLL;
af.modifier = IS_NPC(ch) ? ch->level / 2 : ch->damroll * 2 / 3;
affect_to_char2(ch, &af);
af.location = APPLY_HITROLL;
af.modifier = IS_NPC(ch) ? ch->level / 2 : ch->hitroll * 2 / 3;
affect_to_char2(ch, &af);
af.location = APPLY_AC;
af.modifier = ch->level * -2;
affect_to_char2(ch, &af);
send_to_char(AT_WHITE, "You go into a frenzy.\n\r",ch);
act(AT_WHITE, "$n suddenly goes into a frenzy", ch, NULL, NULL, TO_ROOM );
update_skpell( ch, gsn_frenzy );
return;
}
void do_reflex( CHAR_DATA *ch, char *argument )
{
AFFECT_DATA af;
if ( IS_NPC( ch ) )
return;
if ( IS_AFFECTED( ch, AFF_HASTE ) )
return;
if ( !can_use_skpell( ch, gsn_reflex ) )
return;
WAIT_STATE( ch, skill_table[gsn_reflex].beats );
if ( ch->pcdata->learned[gsn_reflex] < number_percent( ) )
{
send_to_char( C_DEFAULT, "You failed.\n\r", ch );
return;
}
send_to_char( AT_RED, "You feel yourself more agile.\n\r", ch );
act( AT_WHITE, "$n is moving more fluidly.", ch, NULL, NULL, TO_ROOM );
af.type = gsn_reflex;
af.level = ch->level;
af.duration = ch->level / 4;
af.location = APPLY_DEX;
af.modifier = 4;
af.bitvector = AFF_HASTE;
affect_to_char( ch, &af );
update_skpell( ch, gsn_reflex );
return;
}
void do_rake( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_rake ) )
{
send_to_char(C_DEFAULT,
"You'd better leave animalistic actions to werewolves.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
if ( IS_AFFECTED( victim, AFF_BLIND ) )
return;
WAIT_STATE( ch, skill_table[gsn_rake].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_rake] )
{
damage( ch, victim, number_range( 100, ch->level*5 ), gsn_rake );
update_skpell( ch, gsn_rake );
if ( number_percent( ) < 75 )
{
AFFECT_DATA af;
af.type = gsn_blindness;
af.duration = 5;
af.location = APPLY_HITROLL;
af.modifier = -10;
af.bitvector = AFF_BLIND;
affect_join( victim, &af );
}
update_pos( victim );
}
else
damage( ch, victim, 0, gsn_rake );
return;
}
void do_bladepalm( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
int dam = 0;
if ( IS_NPC( ch ) )
return;
if ( !can_use_skpell( ch, gsn_bladepalm ) )
{
send_to_char( AT_GREY, "You know nothing of martial arts.\n\r", ch );
return;
}
if ( get_eq_char( ch, WEAR_WIELD ) && get_eq_char( ch, WEAR_WIELD_2 ) )
{
send_to_char( AT_GREY, "You need at least one free hand to perform a blade palm.\n\r", ch );
return;
}
if ( argument[0] != '\0' )
{
if ( !(victim=get_char_room(ch, argument)) )
{
send_to_char(C_DEFAULT, "They aren't there.\n\r", ch );
return;
}
}
else
{
if ( !(victim = ch->fighting) )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
}
if ( is_safe(ch, victim) )
return;
WAIT_STATE(ch, skill_table[gsn_bladepalm].beats);
if ( ch->pcdata->learned[gsn_bladepalm] > number_percent( ) )
{
int anatomy = ch->pcdata->learned[gsn_anatomyknow];
if ( anatomy > 0
&& number_percent( ) < number_range( anatomy / 9, anatomy / 4.5 ) )
{
update_skpell( ch, gsn_anatomyknow );
send_to_char( AT_RED, "You hit a pressure point!\n\r", ch );
act( AT_RED, "$n hit one of $N's pressure points!",
ch, NULL, victim, TO_NOTVICT );
act( AT_RED, "$n hit you with a precise shot.",
ch, NULL, victim, TO_VICT );
if ( number_percent( ) < 5 )
{
victim->hit = 1;
}
else if ( number_percent( ) < 25 )
{
STUN_CHAR( victim, 3, STUN_TOTAL );
victim->position = POS_STUNNED;
dam += 500;
}
else
dam += 300;
}
dam += number_fuzzy( ch->level / 2 + ch->level / 15 );
dam += GET_DAMROLL( ch );
if ( is_affected( ch, gsn_flamehand ) )
dam += dam / 8;
if ( is_affected( ch, gsn_frosthand ) )
dam += dam / 4;
if ( is_affected( ch, gsn_chaoshand ) )
dam += dam / 4;
if ( ch->pcdata->learned[gsn_enhanced_damage] > 0 )
dam += dam / 4 * ch->pcdata->learned[gsn_enhanced_damage] / 150;
damage( ch, victim, dam, gsn_bladepalm );
update_skpell( ch, gsn_bladepalm );
}
else
damage( ch, victim, 0, gsn_bladepalm );
return;
}
void do_flyingkick( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg[ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_flykick ) )
{
send_to_char( AT_GREY, "You do not hav knowledge of martial arts.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char( AT_GREY, "You aren't fighting anyone.\n\r", ch );
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !(victim=get_char_room( ch, arg )) )
{
send_to_char( AT_GREY, "They aren't here.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[gsn_flykick].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_flykick] )
{
damage( ch, victim, number_range( 200, ch->level*6 ), gsn_flykick );
update_skpell( ch, gsn_flykick );
}
else
damage( ch, victim, 0, gsn_flykick );
return;
}
void do_nerve( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char buf[MAX_INPUT_LENGTH];
OBJ_DATA *wield;
OBJ_DATA *dual;
OBJ_DATA *hold;
OBJ_DATA *triple;
if ( IS_NPC( ch ) )
return;
if ( !can_use_skpell( ch, gsn_nerve ) )
{
send_to_char( AT_GREY, "Huh?\n\r", ch );
return;
}
if ( !(victim = ch->fighting) )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r",ch);
return;
}
if ( number_percent() < ch->pcdata->learned[gsn_nerve]
&& number_percent() < (ch->level * 75) / victim->level )
{
AFFECT_DATA af;
act( AT_YELLOW, "You pinch $N's arm nerves!", ch, NULL, victim, TO_CHAR );
act( AT_YELLOW, "$n pinched your arm nerves.", ch, NULL, victim, TO_VICT );
act( AT_YELLOW, "$n pinched $N's arm nerves.", ch, NULL, victim, TO_NOTVICT );
wield = get_eq_char( victim, WEAR_WIELD );
dual = get_eq_char( victim, WEAR_WIELD_2 );
triple = get_eq_char( victim, WEAR_WIELD_3 );
if ( wield || dual || triple )
{
if ( IS_SIMM( victim, IMM_NERVE ) )
{
sprintf( buf,
"$N shrugs off the blow and grips $S weapon%s tightly.",
( wield && dual ) ? "s" : "" );
act( AT_GREY, buf, ch, NULL, victim, TO_NOTVICT );
}
else
{
sprintf( buf, "$N drops $S weapon%s to the ground.",
( wield && dual ) ? "s" : "" );
act( AT_GREY, buf, ch, NULL, victim, TO_CHAR );
act( AT_GREY, buf, ch, NULL, victim, TO_NOTVICT );
sprintf( buf, "You drop your weapon%s to the ground.\n\r",
( wield && dual ) ? "s" : "" );
send_to_char( AT_GREY, buf, victim );
if ( wield )
{
obj_from_char( wield );
obj_to_room( wield, victim->in_room );
}
if ( dual )
{
obj_from_char( dual );
obj_to_room( dual, victim->in_room );
}
if ( triple )
{
obj_from_char( triple );
obj_to_room( triple, victim->in_room );
}
}
}
if ( (hold = get_eq_char( victim, WEAR_HOLD )) )
{
if ( !IS_SIMM( victim, IMM_NERVE ) )
{
act( AT_GREY, "$N drops $S $p.", ch, hold, victim, TO_CHAR );
act( AT_GREY, "$N drops $S $p.", ch, hold, victim, TO_NOTVICT );
act( AT_GREY, "You drop your $p.", ch, hold, victim, TO_VICT );
obj_from_char( hold );
obj_to_room( hold, victim->in_room );
}
else
act( AT_GREY, "$N grips $S $p tightly.", ch, hold, victim, TO_NOTVICT );
}
if ( IS_SIMM( ch, IMM_NERVE ) )
return;
af.type = gsn_nerve;
af.duration = 1;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = 0;
affect_join( victim, &af );
update_skpell( ch, gsn_nerve );
}
return;
}
void do_trip( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
if ( IS_NPC( ch ) )
return;
if ( !can_use_skpell( ch, gsn_trip ) )
{
send_to_char( AT_GREY, "Huh?\n\r", ch );
return;
}
if ( !(victim=ch->fighting) )
{
send_to_char( AT_GREY, "You aren't fighting anyone.\n\r", ch );
return;
}
if ( ch->pcdata->learned[gsn_trip] > number_percent( ) )
{
trip( ch, victim );
update_skpell( ch, gsn_trip );
}
return;
}
void do_shriek( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
OBJ_DATA *obj, *obj_next;
OBJ_DATA *potion, *potion_next;
int dam;
int blown = 0;
int max_blown = 0;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_shriek ) )
{
send_to_char( AT_GREY, "Huh?\n\r", ch );
return;
}
if ( !(victim = ch->fighting) )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
max_blown = ( IS_NPC( ch ) ) ? 10 : 25;
if ( ( obj = victim->carrying ) && !saves_spell( ch->level, victim ) )
{
for ( obj = victim->carrying; obj; obj = obj_next )
{
obj_next = obj->next_content;
if ( blown >= max_blown )
break;
if ( obj->deleted )
continue;
switch ( obj->item_type )
{
default: continue;
case ITEM_POTION:
case ITEM_CONTAINER:
}
if ( obj->item_type == ITEM_CONTAINER )
{
if ( !obj->contains )
continue;
for ( potion = obj->contains; potion; potion = potion_next )
{
potion_next = potion->next_content;
if ( blown >= max_blown )
break;
if ( potion->deleted )
continue;
if ( potion->item_type != ITEM_POTION )
continue;
if ( number_bits( 2 ) != 0 )
{
extract_obj( potion );
act(AT_BLUE, "You feel something explode from within $p.",
victim, obj, NULL, TO_CHAR );
blown++;
}
}
continue;
}
if ( number_bits( 2 ) != 0 )
{
act(AT_BLUE, "$p vibrates and explodes!", victim, obj, NULL, TO_CHAR );
extract_obj( obj );
blown++;
}
}
}
dam = number_range( 100, ch->level * 3 );
dam += blown * 10;
damage( ch, victim, dam, gsn_shriek );
update_skpell( ch, gsn_shriek );
WAIT_STATE( ch, skill_table[gsn_shriek].beats );
}
void death_xp_loss( CHAR_DATA *victim )
{
int base_xp, xp_lastlvl, xp_loss, classes, mod;
classes = number_classes( victim );
if ( victim->level < LEVEL_HERO )
{
xp_lastlvl = classes == 1 ? 1000 * victim->level
: classes * 2000 * victim->level;
xp_loss = ( xp_lastlvl - victim->exp ) / 2;
if ( victim->exp > xp_lastlvl )
gain_exp( victim, xp_loss );
}
else if ( victim->level < L_CHAMP3 )
{
mod = 1;
base_xp = classes == 1 ? 100000 : 200000;
xp_lastlvl = base_xp * classes;
switch ( victim->level )
{
case LEVEL_HERO: mod = 1;
case L_CHAMP1: mod = 4;
case L_CHAMP2: mod = 10;
}
xp_lastlvl = xp_lastlvl * mod;
if ( victim->exp > xp_lastlvl )
{
xp_loss = (xp_lastlvl - victim->exp ) / 2;
xp_loss = UMAX( -10000 * classes, xp_loss );
gain_exp( victim, xp_loss );
}
}
return;
}
void do_lure( CHAR_DATA *ch, char *argument )
{
char dt;
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, gsn_lure ) )
{
send_to_char(C_DEFAULT,
"You cannot lure.\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
/* if ( !( obj = get_eq_char( ch, WEAR_WIELD ) )
|| ( obj->value[3] != 11 && obj->value[3] != 2 ) )
{
send_to_char(C_DEFAULT, "You need to wield a piercing or stabbing
weapon.\n\r", c$
return;
} */
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_blindfight] > 0
&& ch->pcdata->learned[gsn_blindfight] < number_percent( ) )
{
if ( !check_blind( ch ) )
return;
}
one_argument( argument, arg );
victim = ch->fighting;
if ( arg[0] != '\0' )
if ( !( victim = get_char_room( ch, arg ) ) )
{
send_to_char(C_DEFAULT, "They aren't here.\n\r", ch );
return;
}
dt = TYPE_UNDEFINED;
WAIT_STATE( ch, skill_table[gsn_lure].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_lure] )
{
act(AT_WHITE, "$n lures $N into a vulnerable position.", ch, NULL, victim, TO_ROOM );
send_to_char( AT_WHITE, "Your oppenet has lured you into a vulnerable position.\n\r", victim );
send_to_char( AT_WHITE, "You lure your opponent into a vulnerable position.\n\r", ch);
one_hit( ch, victim, dt );
if(IS_AFFECTED(ch, AFF_HASTE))
one_hit( ch, victim, dt );
if (IS_AFFECTED2( ch, AFF_RUSH ) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_second_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_third_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_fourth_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_fifth_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_sixth_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_seventh_attack) )
one_hit( ch, victim, dt );
/* if(can_use_skpell( ch, gsn_eigth_attack) )
one_hit( ch, victim, dt ); */
if ( IS_AFFECTED2(ch, AFF_BERSERK) )
one_hit( ch, victim, dt );
/* put more reasons to attack here */
one_dual( ch, victim, dt);
one_triple( ch, victim, dt);
}
update_skpell( ch, gsn_lure );
return;
}
void do_image( CHAR_DATA *ch, CHAR_DATA *victim )
{
char dt;
char buf[MAX_STRING_LENGTH];
dt = TYPE_UNDEFINED;
act(AT_WHITE, "$n attacks $N!", ch, NULL, victim, TO_ROOM );
act( AT_WHITE, "An image of $n shatters!", ch, NULL, NULL, TO_ROOM
);
sprintf( buf, "An image of %s shatters!\n\r", ch->name );
send_to_char( AT_WHITE, buf, victim );
sprintf( buf, "%s attacks one of your images!", victim->name );
send_to_char( AT_WHITE, buf, ch);
one_hit( ch, victim, dt );
if(IS_AFFECTED(ch, AFF_HASTE))
one_hit( ch, victim, dt );
if (IS_AFFECTED2( ch, AFF_RUSH ) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_second_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_third_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_fourth_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_fifth_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_sixth_attack) )
one_hit( ch, victim, dt );
if(can_use_skpell( ch, gsn_seventh_attack) )
one_hit( ch, victim, dt );
/* if(can_use_skpell( ch, gsn_eigth_attack) )
one_hit( ch, victim, dt ); */
if ( IS_AFFECTED2(ch, AFF_BERSERK) )
one_hit( ch, victim, dt );
/* put more reasons to attack here */
one_dual( ch, victim, dt);
one_triple( ch, victim, dt);
multi_hit( ch, victim, dt );
return;
}
void do_flip(CHAR_DATA *ch, char *argument)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
EXIT_DATA *pexit;
CHAR_DATA *victim;
ROOM_INDEX_DATA *from_room;
int door;
char buf1[256], buf2[256], buf3[256];
argument = one_argument(argument, arg1);
one_argument(argument, arg2);
if(arg1[0] == '\0')
{
send_to_char(AT_BLUE, "Flip who what where?", ch);
return;
}
if((victim = get_char_room(ch, arg1)) == NULL)
{
send_to_char(AT_BLUE, "They aren't here.\n\r", ch);
return;
}
if(victim->position != POS_FIGHTING)
{
send_to_char(AT_BLUE, "You aren't fighting anybody.\n\r", ch);
return;
}
WAIT_STATE( ch, skill_table[gsn_flip].beats );
if ( IS_NPC( ch ) || number_percent( ) < ch->pcdata->learned[gsn_flip] )
{
damage( ch, victim, number_range( 100, ch->level*6 ), gsn_flip );
}
else
damage( ch, victim, 0, gsn_flip );
if ( victim->position == POS_STUNNED || IS_STUNNED( ch, STUN_TO_STUN ) )
return;
if ( ( IS_NPC(ch) || number_percent() < ch->pcdata->learned[gsn_flip] ) &&
number_percent() < (ch->level * 100) / victim->level )
{
STUN_CHAR( ch, 10, STUN_TO_STUN );
STUN_CHAR( victim, 3, STUN_TOTAL );
victim->position = POS_STUNNED;
act( AT_WHITE, "You knock the wind out of $N!", ch, NULL, victim, TO_CHAR );
act( AT_WHITE, "$n knocks the wind out of $N!", ch, NULL, victim, TO_NOTVICT );
act( AT_WHITE, "$n knocks the wind out of you!", ch, NULL, victim, TO_VICT );
update_skpell(ch, gsn_flip);
}
if ( !str_cmp( arg2, "n" ) || !str_cmp( arg2, "north" ) ) door = 0;
else if ( !str_cmp( arg2, "e" ) || !str_cmp( arg2, "east" ) ) door = 1;
else if ( !str_cmp( arg2, "s" ) || !str_cmp( arg2, "south" ) ) door = 2;
else if ( !str_cmp( arg2, "w" ) || !str_cmp( arg2, "west" ) ) door = 3;
else if ( !str_cmp( arg2, "u" ) || !str_cmp( arg2, "up" ) ) door = 4;
else if ( !str_cmp( arg2, "d" ) || !str_cmp( arg2, "down" ) ) door = 5;
else door = dice(1,6) - 1;
if(ch == victim)
{
send_to_char(AT_BLUE, "You attempt to flip yourself, oook.\n\r", ch);
return;
}
pexit = ch->in_room->exit[door];
if(pexit == NULL || IS_SET(pexit->exit_info, EX_CLOSED))
{
act(AT_BLUE, "There is no exit, but you flip $M anyways.", ch, NULL,
victim, TO_CHAR);
act(AT_BLUE, "$n flips $N.", ch, NULL, victim, TO_NOTVICT);
act(AT_BLUE, "$n flips you, ouch.", ch, NULL, victim, TO_VICT);
return;
}
if (!can_use_skpell( ch, gsn_flip ))
{
send_to_char(AT_WHITE, "HEEEYaaaaAA!", ch );
return;
}
if ( pexit->to_room->vnum == ROOM_VNUM_SMITHY )
{
act(AT_BLUE, "You flip $N, but a force field prevents $S entry.",
ch, NULL, victim, TO_CHAR );
act(AT_BLUE, "$n flips $N, but a force field makes $M bounce back.", ch, NULL, victim, TO_NOTVICT );
act(AT_BLUE, "$n flips you, but you bounce off of a force field.",
ch, NULL, victim, TO_VICT );
return;
}
if ( number_percent( ) < ch->pcdata->learned[gsn_flip] ){
sprintf(buf1, "You flip $N, sending $M %s.", dir_name[door]);
sprintf(buf2, "$n flips $N, sending $M %s.", dir_name[door]);
sprintf(buf3, "$n flips you, sending you %s.", dir_name[door]);
act(AT_BLUE, buf2, ch, NULL, victim, TO_NOTVICT );
act(AT_BLUE, buf1, ch, NULL, victim, TO_CHAR );
act(AT_BLUE, buf3, ch, NULL, victim, TO_VICT );
from_room = victim->in_room;
eprog_enter_trigger( pexit, victim->in_room, victim );
char_from_room(victim);
char_to_room(victim, pexit->to_room);
act(AT_BLUE, "$n comes flying into the room.", victim, NULL, NULL,
TO_ROOM);
if ( (pexit = pexit->to_room->exit[rev_dir[door]]) &&
pexit->to_room == from_room )
eprog_exit_trigger( pexit, victim->in_room, victim );
else
rprog_enter_trigger( victim->in_room, victim );
}
return;
}