/*******************/
/* Detlef's Extras */
/*******************/
#include "include.h"
DECLARE_DO_FUN(do_myell);
DECLARE_DO_FUN(do_yell);
#define LOGIN_LOG_FILE "logins.txt"
#define TEMP_GREP_RESULTS_TWO "../temp/tempgrepresults2.tmp"
int battlecry_multiplier args((CHAR_DATA *ch, int dt));
char *target_name;
bool IS_IMP(CHAR_DATA *ch)
{
if(get_trust(ch)==MAX_LEVEL)
return TRUE;
return FALSE;
}
void do_gouge( CHAR_DATA *ch, char *argument )
{
bool attempt_dual;
char arg[MAX_INPUT_LENGTH];
AFFECT_DATA af;
CHAR_DATA *victim;
OBJ_DATA *obj;
int chance;
int dam;
attempt_dual = FALSE;
one_argument(argument,arg);
if ( (chance = get_skill(ch,gsn_gouge)) == 0
|| IS_NPC(ch)
|| (!IS_NPC(ch) && ch->level < skill_table[gsn_gouge].skill_level[ch->class]) )
{
send_to_char("Huh?\n\r",ch);
return;
}
if (arg[0] == '\0')
{
victim = ch->fighting;
if (victim == NULL)
{
send_to_char("But you aren't fighting anyone.\n\r",ch);
return;
}
}
else if ((victim = get_char_room(ch,arg)) == NULL)
{
send_to_char("They aren't here.\n\r",ch);
return;
}
if (ch->fighting == NULL)
{
send_to_char("You can't gouge someone's eye like that.\n\r",ch);
return;
}
if (is_affected(victim,gsn_gouge) )
{
send_to_char("Their eye is already gouged.\n\r",ch);
return;
}
if (victim == ch)
{
send_to_char("Huh?\n\r", ch);
return;
}
obj = get_eq_char(ch,WEAR_WIELD);
if (obj == NULL || obj->value[0] != WEAPON_DAGGER)
{
attempt_dual = TRUE;
obj = get_eq_char(ch,WEAR_DUAL_WIELD);
}
if (obj == NULL || obj->value[0] != WEAPON_DAGGER)
{
attempt_dual = TRUE;
obj = get_eq_char(ch,WEAR_TERTIARY_WIELD);
}
if (obj == NULL)
{
send_to_char("You must wield a dagger to gouge someone.\n\r",ch);
return;
}
if (obj->value[0] != 2)
{
send_to_char("You must wield a dagger to gouge someone.\n\r",ch);
return;
}
chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);
WAIT_STATE(ch,skill_table[gsn_gouge].beats);
if (number_percent() < chance - 40)
{
act("You attempt to gouge at $N's eye.",ch,NULL,victim,TO_CHAR);
act("$n attempts to gouge at your eye.",ch,NULL,victim,TO_VICT);
act("$n attempts to gouge at $N's eye.",ch,NULL,victim,TO_NOTVICT);
act("$N appears to be blinded.",ch,NULL,victim,TO_CHAR);
act("You are blinded.",ch,NULL,victim,TO_VICT);
act("$N appears to be blinded.",ch,NULL,victim,TO_NOTVICT);
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SKILL;
af.duration = ch->level/25;
af.bitvector = AFF_BLIND;
af.type=gsn_gouge;
af.level = ch->level;
af.location = APPLY_HITROLL;
af.modifier = -5;
affect_to_char(victim,&af);
check_improve(ch,gsn_gouge,TRUE,1);
dam = dice(obj->value[1],obj->value[2]);
dam += 10;
WAIT_STATE(ch,PULSE_VIOLENCE*1);
if ((ch->drain_level + ch->level) <= 15)
dam *= 2;
else if ((ch->drain_level + ch->level) <= 20)
dam *= 2.5;
else if ((ch->drain_level + ch->level) < 25)
dam *= 3;
else if ((ch->drain_level + ch->level) < 30)
dam *= 3.5;
else if ((ch->drain_level + ch->level) < 40)
dam *= 4;
else if ((ch->drain_level + ch->level) <= 49)
dam *= 4.5;
else if ((ch->drain_level + ch->level) <= 55)
dam *= 5;
else dam *= 5;
dam *= battlecry_multiplier(ch,gsn_gouge);
damage_old(ch,victim,dam,gsn_gouge, attack_table[obj->value[3]].damage, TRUE);
}
else
{
check_improve(ch,gsn_gouge,FALSE,1);
damage_old(ch,victim,0,gsn_gouge,DAM_NONE,TRUE);
}
return;
}
void do_stab( CHAR_DATA *ch, char *argument )
{
bool attempt_dual;
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
OBJ_DATA *obj;
int chance;
int dam;
attempt_dual = FALSE;
one_argument(argument,arg);
if ( (chance = get_skill(ch,gsn_stab)) == 0
|| IS_NPC(ch)
|| (!IS_NPC(ch) && ch->level < skill_table[gsn_stab].skill_level[ch->class]) )
{
send_to_char("Huh?\n\r",ch);
return;
}
if (arg[0] == '\0')
{
victim = ch->fighting;
if (victim == NULL)
{
send_to_char("But you aren't fighting anyone.\n\r",ch);
return;
}
}
else if ((victim = get_char_room(ch,arg)) == NULL)
{
send_to_char("They aren't here.\n\r",ch);
return;
}
if (ch->fighting == NULL)
{
send_to_char("You can't stab someone like that.\n\r",ch);
return;
}
if (victim == ch)
{
send_to_char("Huh?\n\r", ch);
return;
}
obj = get_eq_char(ch,WEAR_WIELD);
if (obj == NULL || obj->value[0] != WEAPON_DAGGER)
{
attempt_dual = TRUE;
obj = get_eq_char(ch,WEAR_DUAL_WIELD);
}
if (obj == NULL || obj->value[0] != WEAPON_DAGGER)
{
attempt_dual = TRUE;
obj = get_eq_char(ch,WEAR_TERTIARY_WIELD);
}
if (obj == NULL)
{
send_to_char("You must wield a dagger to stab someone.\n\r",ch);
return;
}
if (obj->value[0] != 2)
{
send_to_char("You must wield a dagger to stab someone.\n\r",ch);
return;
}
chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);
chance = URANGE(5, chance, 95);
WAIT_STATE(ch,skill_table[gsn_stab].beats);
if (number_percent() < chance)
{
act("You unleash with a viscious stab on $N.",ch,NULL,victim,TO_CHAR);
act("$n unleashes with a viscious stab.",ch,NULL,victim,TO_VICT);
act("$n unleashes with a viscious stab on $N.",ch,NULL,victim,TO_NOTVICT);
check_improve(ch,gsn_stab,TRUE,1);
dam = dice(obj->value[1],obj->value[2]);
dam += 40;
if ((ch->drain_level + ch->level) <= 15)
dam *= 1;
else if ((ch->drain_level + ch->level) <= 20)
dam *= 2;
else if ((ch->drain_level + ch->level) < 25)
dam *= 2.5;
else if ((ch->drain_level + ch->level) < 30)
dam *= 3;
else if ((ch->drain_level + ch->level) < 40)
dam *= 3.5;
else if ((ch->drain_level + ch->level) <= 49)
dam *= 4;
else if ((ch->drain_level + ch->level) <= 55)
dam *= 4.5;
else dam *= 4.5;
dam *= battlecry_multiplier(ch,gsn_stab);
damage_old(ch,victim,dam,gsn_stab, attack_table[obj->value[3]].damage, TRUE);
}
else
{
check_improve(ch,gsn_stab,FALSE,1);
damage_old(ch,victim,0,gsn_stab,DAM_NONE,TRUE);
}
return;
}
void spell_dream_blossom(int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
ROOM_AFFECT_DATA af;
AFFECT_DATA af2;
if ((ch->in_room->sector_type == SECT_CITY) || (ch->in_room->sector_type == SECT_INSIDE))
{
send_to_char("You must be in the wilderness to call the Dream Blossoms.\n\r",ch);
return;
}
if (IS_SET(ch->in_room->room_flags, ROOM_LAW))
{
send_to_char("This room is protected by gods.\n\r", ch);
return;
}
if (cabal_down(ch,CABAL_BRIAR))
{
send_to_char("You cannot find the power within you.\n\r",ch);
return;
}
if ( is_affected(ch,gsn_dream_blossom))
{
send_to_char("You cannot call the Dream Blossoms again so soon.\n\r",ch);
return;
}
if ( is_affected_room( ch->in_room, sn ))
{
send_to_char("The dream blossoms are already growing here.\n\r",ch);
return;
}
init_affect(&af2);
af2.where = TO_AFFECTS;
af2.type = gsn_dream_blossom;
af2.aftype = AFT_SKILL;
af2.level = ch->level;
af2.duration = 24;
af2.location = 0;
af2.modifier = 0;
af2.bitvector = 0;
affect_to_char(ch,&af2);
init_affect_room(&af);
af.where = TO_ROOM_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = ch->level;
af.duration = 8;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_ROOM_SLEEP;
affect_to_room( ch->in_room, &af );
check_improve(ch,gsn_dream_blossom,TRUE,1);
WAIT_STATE(ch,12);
send_to_char("Tiny sprouts shoot from the ground as you command the Dream Blossom to grow in this area.\n\r",ch);
act("The seductive smell of flowers pervades the area.\n\r",ch,NULL,NULL,TO_ROOM);
}
void spell_randomizer(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
ROOM_AFFECT_DATA af2;
if ( is_affected( ch, sn ) )
{
send_to_char
("Your power of randomness has been exhausted for now.\n\r",
ch);
return;
}
if (IS_SET(ch->in_room->room_flags, ROOM_LAW))
{
send_to_char(
"This room is far too orderly for your powers to work on it.\n\r",
ch);
return;
}
if ( is_affected_room( ch->in_room, sn ))
{
send_to_char("This room has already been randomized.\n\r",ch);
return;
}
if (number_bits(1) == 0)
{
send_to_char("Despite your efforts, the universe resisted chaos.\n\r",ch);
af2.where = TO_AFFECTS;
af2.type = sn;
af2.level = ch->level;
af2.duration = level / 10;
af2.modifier = 0;
af2.location = APPLY_NONE;
af2.bitvector = 0;
affect_to_char( ch, &af );
return;
}
init_affect(&af);
af.where = TO_ROOM_AFFECTS;
af.type = sn;
af.aftype = AFT_POWER;
af.level = ch->level;
af.duration = level / 15;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_ROOM_RANDOMIZER;
affect_to_room( ch->in_room, &af2 );
init_affect_room(&af2);
af2.where = TO_AFFECTS;
af2.type = sn;
af2.aftype = AFT_POWER;
af2.level = ch->level;
af2.duration = level / 5;
af2.modifier = 0;
af2.location = APPLY_NONE;
af2.bitvector = 0;
affect_to_char( ch, &af );
send_to_char("The room was successfully randomized!\n\r", ch);
send_to_char("You feel very drained from the effort.\n\r", ch);
ch->hit -= UMIN(200, ch->hit/2);
act("The room starts to randomize exits.",ch,NULL,NULL,TO_ROOM);
return;
}
void do_newbie( CHAR_DATA *ch, char *argument )
{
if(ch->pcdata->newbie==FALSE)
{
send_to_char("You are not a newbie.\n\r",ch);
return;
}
if(!strcmp(argument,"off"))
{
ch->pcdata->newbie=FALSE;
send_to_char("You are no longer a protected newbie.\n\r",ch);
return;
}
send_to_char("To remove newbie protection, type newbie off.\n\r",ch);
}
char * get_char_color(CHAR_DATA *ch, char *event)
{
int i = get_event_number(event);
if (is_affected(ch,skill_lookup("chromatic fire")))
return color_table[number_range(0,MAX_COLORS-1)].color_ascii;
if ( ch->desc != NULL && ch->desc->original != NULL )
ch = ch->desc->original;
if (IS_NPC(ch))
return "";
if(!IS_SET(ch->comm,COMM_ANSI))
return "";
//if(i>=0)
// return color_name_to_ascii(ch->pcdata->color_scheme[i]);
for(i=0; i < MAX_COLORS; i++)
if(!str_cmp(event,color_table[i].color_name))
return color_table[i].color_ascii;
return "";
}
int get_event_number(char *name)
{
int i;
for(i=0; i<MAX_EVENTS; i++)
if(!str_cmp(name,color_event[i].event_name))
return i;
return -1;
}
char * get_color_name(char *name)
{
int i;
char *tname=str_dup(upstring(name));
for(i=0; i<MAX_COLORS; i++)
if(!str_prefix(tname,upstring(color_table[i].color_name)))
return color_table[i].color_name;
return NULL;
}
char * color_name_to_ascii(char *name)
{
int i;
char *tname=str_dup(upstring(name));
for(i=0; i<MAX_COLORS; i++)
if(!str_cmp(tname,upstring(color_table[i].color_name)))
return color_table[i].color_ascii;
return NULL;
}
char * END_COLOR(CHAR_DATA *ch)
{
if (is_affected(ch,skill_lookup("chromatic fire")))
return color_table[number_range(0,MAX_COLORS-1)].color_ascii;
if (ch->desc != NULL && ch->desc->original != NULL)
{
if (IS_SET(ch->desc->original->comm,COMM_ANSI))
return "\x01B[0m";
else
return "";
}
else
{
if (IS_SET(ch->comm,COMM_ANSI))
return "\x01B[0m";
else
return "";
}
return "";
}
void do_snare( CHAR_DATA *ch, char *argument )
{
ROOM_AFFECT_DATA af;
AFFECT_DATA snaretimer;
if(get_skill(ch,gsn_snare)<5)
{
send_to_char("You lay some sticks down in a threatening snare to anyone under an inch tall.\n\r",ch);
return;
}
if(is_affected(ch,gsn_snaretimer))
{
send_to_char("You do not feel ready to lay a new snare yet.\n\r",ch);
return;
}
if(is_affected_room(ch->in_room,gsn_snare))
{
send_to_char("There is already a snare here.\n\r",ch);
return;
}
if((ch->in_room->sector_type!=SECT_FOREST &&
ch->in_room->sector_type!=SECT_MOUNTAIN &&
ch->in_room->sector_type!=SECT_DESERT &&
ch->in_room->sector_type!=SECT_FIELD &&
ch->in_room->sector_type!=SECT_HILLS &&
!IS_IMMORTAL(ch)) ||
(ch->in_room->vnum==5700 || ch->in_room->cabal))
{
send_to_char("You cannot create a snare in this environment.\n\r",ch);
return;
}
init_affect_room(&af);
af.where = TO_ROOM_AFFECTS;
af.aftype = AFT_SKILL;
af.type = gsn_snare;
af.level = ch->level;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = 0;
af.owner = ch;
af.end_fun = NULL;
af.tick_fun = NULL;
new_affect_to_room(ch->in_room, &af);
init_affect(&snaretimer);
snaretimer.where = TO_AFFECTS;
snaretimer.type = gsn_snaretimer;
snaretimer.level = ch->level;
snaretimer.duration = 24;
snaretimer.location = APPLY_NONE;
snaretimer.modifier = 0;
snaretimer.bitvector = 0;
snaretimer.aftype = AFT_SKILL;
affect_to_char(ch,&snaretimer);
send_to_char("You lay down vines and plants in a cunningly concealed snare to trap the unwary.\n\r",ch);
act("$n lays down vines and plants in a cunningly concealed snare to trap the unwary.\n\r",ch,0,0,TO_ROOM);
WAIT_STATE(ch,PULSE_VIOLENCE*4);
}
bool auto_check_multi(DESCRIPTOR_DATA *d_check, char *host)
{
DESCRIPTOR_DATA *d;
for (d = descriptor_list; d != NULL; d = d->next)
{
if (d == d_check || d->character == NULL)
continue;
if (!str_cmp(host,d->host))
return TRUE;
}
return FALSE;
}
void chop(char *str)
{
str[strlen(str)-1] = '\0';
return;
}
void chomp(char *str)
{
for (; *str != '\0'; str++)
{
if ( *str == '\n' || *str == '\r')
*str = '\0';
}
return;
}
void do_crumble( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
CHAR_DATA *victim;
OBJ_DATA *obj;
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
argument = one_argument(argument, arg3);
if ( arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
{
send_to_char( "Syntax: crumble <char> <inv/eq> <item>\n\r", ch );
return;
}
if ((victim = get_char_world(ch, arg1)) == NULL)
{
send_to_char( "They aren't here.\n\r", ch );
return;
}
if (get_trust(victim) > get_trust(ch)) {
send_to_char( "You can't do that.\n\r", ch );
return;
}
if (!str_prefix(arg2,"inventory")) {
if ((obj = get_obj_carry(victim,arg3,ch)) == NULL )
{
send_to_char( "You can't find it.\n\r", ch );
return;
}
} else if (!str_prefix(arg2,"equipment")) {
if ((obj = get_obj_wear(victim,arg3)) == NULL )
{
send_to_char( "You can't find it.\n\r", ch );
return;
}
unequip_char(ch,obj);
} else {
send_to_char( "Syntax: crumble <char> <inv/eq> <item>\n\r", ch );
return;
}
obj_from_char(obj);
extract_obj(obj);
act("$p crumbles into dust.", victim, obj, NULL, TO_CHAR);
act("$N: $p crumbles into dust.", ch, obj, victim, TO_CHAR);
return;
}
void spell_looking_glass( int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = number_range( 3,7 );
af.modifier = MOD_NONE;
af.bitvector = AFF_LOOKING_GLASS;
affect_to_char( victim, &af );
send_to_char( "You pass through a looking glass and everything seems suddenly strange.\n\r", victim );
act("$n passed through the looking glass to the world beyond.",victim,NULL,NULL,TO_ROOM);
return;
}
void update_pc_last_fight(CHAR_DATA *ch,CHAR_DATA *ch2)
{
if (IS_NPC(ch) || IS_NPC(ch2) || ch==ch2)
return;
ch->last_fight_time = current_time;
ch->last_fight_name = ch2->name;
ch2->last_fight_time = current_time;
ch2->last_fight_name = ch->name;
return;
}
void do_weaponbreak(CHAR_DATA *ch, CHAR_DATA *victim )
{
int chance;
OBJ_DATA *wield;
bool using_primary = TRUE;
chance = get_skill(ch,gsn_weaponbreaker);
if (chance == 0
|| (ch->level < skill_table[gsn_weaponbreaker].skill_level[ch->class]
&& !IS_NPC(ch)))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (!is_wielded(ch,WEAPON_AXE,WIELD_ONE)) {
send_to_char("You must be wielding an axe to do that.\n\r",ch);
return;
}
if ( ( victim = ch->fighting ) == NULL )
{
send_to_char( "You aren't fighting anyone.\n\r", ch );
return;
}
if ((wield = get_eq_char(victim,WEAR_WIELD)) == NULL)
{
send_to_char("But they aren't using a weapon.\n\r",ch);
return;
}
chance *= 9;
chance /= 12;
chance += (ch->level - victim->level)*3;
chance -= wield->level;
if (!using_primary)
chance -= 15;
if(ch->level==60)
chance=1000;
if ((IS_SET(wield->extra_flags,ITEM_FIXED) || IS_OBJ_STAT(wield,ITEM_NODISARM)) && get_trust(ch)!=MAX_LEVEL)
{
act("$n attempts to shatter $N's weapon with $s axe, but it's far too powerful for that.",ch,0,victim,TO_NOTVICT);
act("$n attempts to shatter your weapon with $s axe, but it's far too powerful for that.",ch,0,victim,TO_VICT);
act("You attempt to shatter $N's weapon with your axe, but it's far too powerful for that.",ch,0,victim,TO_CHAR);
WAIT_STATE(ch,2*PULSE_VIOLENCE);
return;
}
if (number_percent() > chance)
{
act("$n attempts to shatter $N's weapon with $S axe, but it holds firm.",ch,0,victim,TO_NOTVICT);
act("$n attempts to shatter your weapon with $S axe, but it holds firm.",ch,0,victim,TO_VICT);
act("You attempt to shatter $N's weapon with your axe, but it holds firm.",ch,0,victim,TO_CHAR);
check_improve(ch,gsn_weaponbreaker,FALSE,1);
WAIT_STATE(ch,2*PULSE_VIOLENCE);
multi_hit(victim,ch,-1);
return;
}
act("$n's mighty blow shatters $p!",ch,wield,victim,TO_NOTVICT);
act("Your mighty blow shatters $p!",ch,wield,victim,TO_CHAR);
act("$n's mighty blow shatters $p!",ch,wield,victim,TO_VICT);
extract_obj(wield);
WAIT_STATE(ch,2*PULSE_VIOLENCE);
check_improve(ch,gsn_weaponbreaker,TRUE,1);
multi_hit(victim,ch,-1);
return;
}
void spell_barrier( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if(is_affected(victim,gsn_barrier))
{
send_to_char("A mystical barrier already surrounds ",ch);
if(victim!=ch)
send_to_char("them.\n\r",ch);
if(victim==ch)
send_to_char("you.\n\r",ch);
return;
}
if(!IS_IMMORTAL(ch))
victim=ch;
if(IS_AFFECTED(victim,AFF_SANCTUARY) && !IS_IMMORTAL(ch))
{
send_to_char("The interference of your sanctuary causes the magical barrier to flicker and fade away.\n\r",ch);
act("The interference of $n's sanctuary causes $s magical barrier to flicker and fade away.",ch,0,0,TO_ROOM);
WAIT_STATE(ch,PULSE_VIOLENCE*2);
ch->mana-=20;
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.type = gsn_barrier;
af.level = level;
af.location = APPLY_AC;
af.modifier = -50;
af.duration = 8;
af.bitvector = 0;
af.aftype = AFT_SPELL;
affect_to_char(victim,&af);
act("$n is surrounded by a mystical barrier.",victim,0,0,TO_ROOM);
send_to_char("You are surrounded by a mystical barrier.\n\r",victim);
}
void update_sitetrack(CHAR_DATA *ch, char *site)
{
char *allsites = NULL;
char site1[MAX_STRING_LENGTH];
char site2[MAX_STRING_LENGTH];
char site3[MAX_STRING_LENGTH];
char site4[MAX_STRING_LENGTH];
char site5[MAX_STRING_LENGTH];
char newsite[MAX_STRING_LENGTH];
char string[MAX_STRING_LENGTH];
if (IS_NPC(ch))
return;
free_string(allsites);
if ((allsites = ch->pcdata->sitetrack) != NULL)
{
sprintf(newsite,"%s",site);
allsites = one_argument(allsites, site1);
allsites = one_argument(allsites, site2);
allsites = one_argument(allsites, site3);
allsites = one_argument(allsites, site4);
allsites = one_argument(allsites, site5);
if (site1[0] == '\0') {
sprintf(site1,"%s",newsite);
} else if (site2[0] == '\0') {
sprintf(site2,"%s",newsite);
} else if (site3[0] == '\0') {
sprintf(site3,"%s",newsite);
} else if (site4[0] == '\0') {
sprintf(site4,"%s",newsite);
} else if (site5[0] == '\0') {
sprintf(site5,"%s",newsite);
} else {
sprintf(site1,"%s",site2);
sprintf(site2,"%s",site3);
sprintf(site3,"%s",site4);
sprintf(site4,"%s",site5);
sprintf(site5,"%s",newsite);
}
sprintf(string,"%s %s %s %s %s",site1,site2,site3,site4,site5);
ch->pcdata->sitetrack = str_dup(string);
} else {
ch->pcdata->sitetrack = str_dup(site);
}
return;
}
#if defined(KEY)
#undef KEY
#endif
#define KEY( literal, field, value ) \
if ( !str_cmp( word, literal ) ) \
{ \
field = value; \
fMatch = TRUE; \
break; \
}
/* provided to free strings */
#if defined(KEYS)
#undef KEYS
#endif
void do_finger(CHAR_DATA *ch, char *argument)
{
char arg1[MAX_STRING_LENGTH];
char arg2[MAX_STRING_LENGTH];
char dir[MAX_STRING_LENGTH];
char dir2[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
char buf3[MAX_STRING_LENGTH];
FILE *fp;
int align = -1, class = -1, empire = 0, ethos = -1, kills = -1, gkills = -1, nkills = -1, ekills = -1,
pkilled = -1, mkilled = -1, level = -1, played = -1, cabal = 0, induct = -1, race = -1,
con = 0, stat = 25, died = 0,agemod = 0, bcredits = 0, hometown = 0, aobj = -1, lobj = -1, timeplayed = -1,
vnum = 0, security = 0;
char *history, *name, *login, *title, *extitle, *sex, *allsites, *desc;
bool fMatch = FALSE;
char *word;
bool end = FALSE;
bool dead = FALSE;
char site1[MAX_STRING_LENGTH];
char site2[MAX_STRING_LENGTH];
char site3[MAX_STRING_LENGTH];
char site4[MAX_STRING_LENGTH];
char site5[MAX_STRING_LENGTH];
char eqbuf[MAX_STRING_LENGTH];
BUFFER *output;
long act = 0;
int i;
OBJ_INDEX_DATA *pObjIndex;
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
if (arg1[0] == '\0')
{
send_to_char("Syntax: finger <char>\n\r", ch);
send_to_char(" finger <char> history\n\r", ch);
send_to_char(" finger <char> equipment\n\r", ch);
send_to_char(" finger <char> description\n\r", ch);
return;
}
arg1[0] = UPPER(arg1[0]);
sprintf(buf3,"(none)");
history = NULL;
name = buf3;
login = buf3;
sex = buf3;
title = NULL;
extitle = NULL;
allsites = NULL;
desc = NULL;
sprintf(eqbuf,"Sorry, that is unavailable.\n\r");
sprintf(dir,"%s%s%s",PLAYER_DIR,arg1,".plr");
sprintf(dir2,"%sdead_char/%s%s",PLAYER_DIR,arg1,".plr");
if ( ((fp = fopen(dir, "r" )) != NULL) ) {
dead = FALSE;
} else if ( ((fp = fopen(dir2, "r" )) != NULL) ) {
dead = TRUE;
} else {
send_to_char("No such character.\n\r",ch);
return;
}
for ( ; ; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER(word[0]) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'A':
KEY( "Alig", align, fread_number( fp ) );
KEY( "Act", act, fread_flag( fp ) );
KEY( "Agemod", agemod, fread_number( fp ) );
if (!str_cmp(word,"Attr"))
{
for (stat = 0; stat < MAX_STATS; stat++) {
con = fread_number(fp);
if (stat == STAT_CON)
break;
}
break;
}
break;
case 'B':
KEY( "BCredits", bcredits, fread_number( fp ) );
case 'C':
KEY( "Cla", class, fread_number( fp ) );
KEY( "Cabal", cabal, cabal_lookup(fread_string(fp)));
break;
case 'D':
KEY( "Died", died, fread_number( fp ) );
KEY( "Desc", desc, fread_string( fp ) );
break;
case 'E':
KEY( "Empr", empire, fread_number( fp ) );
KEY( "Etho", ethos, fread_number( fp ) );
KEY( "EXTitl", extitle, fread_string(fp) );
if ( !str_cmp( word, "End" ) )
{
end = TRUE;
}
break;
case 'F':
if (!str_cmp(word,"FingEQ"))
{
eqbuf[0] = '\0';
for (i = 0; i < MAX_WEAR; i++)
{
vnum = fread_number(fp);
if (vnum == 0)
continue;
pObjIndex = get_obj_index(vnum);
sprintf(buf2,"%s%s (%d)\n\r",get_where_name(i), pObjIndex ? pObjIndex->short_descr : "# NON-EXISTANT #", vnum);
strcat(eqbuf,buf2);
}
}
break;
case 'H':
KEY( "History", history, fread_string( fp ) );
KEY( "HomeTown", hometown, fread_number( fp ) );
break;
case 'I':
KEY( "Indu", induct, fread_number( fp ) );
break;
case 'K':
if (!str_cmp(word,"kls"))
{
kills = fread_number( fp );
gkills = fread_number( fp );
nkills = fread_number( fp );
ekills = fread_number( fp );
}
if (!str_cmp(word,"kld"))
{
pkilled = fread_number( fp );
mkilled = fread_number( fp );
}
fMatch = TRUE;
break;
case 'L':
KEY( "Levl", level, fread_number( fp ) );
KEY( "LogonTime", login, fread_string( fp ) );
break;
case 'N':
KEY( "Name", name, fread_string( fp ) );
break;
case 'P':
KEY( "Plyd", played, fread_number( fp ) );
break;
case 'R':
KEY( "Race", race, race_lookup(fread_string( fp )) );
break;
case 'S':
KEY( "Sec", security, fread_number(fp) );
KEY( "Sex", sex, sex_table[fread_number(fp)].name );
KEY( "SiteTrack", allsites, fread_string(fp));
break;
case 'T':
KEY( "Titl", title, fread_string(fp) );
KEY( "TimePlayed", timeplayed, fread_number(fp) );
KEY( "TrackAObj", aobj, fread_number(fp) );
KEY( "TrackLObj", lobj, fread_number(fp) );
break;
}
if ( !fMatch )
{
fread_to_eol( fp );
}
if (arg2[0] != '\0' && !str_prefix(arg2,"history") && history)
break;
if (end)
break;
}
fclose( fp );
if (arg2[0] != '\0' && !str_prefix(arg2,"history")) {
output = new_buf();
sprintf(buf2,"FINGER: %s's player history:\n\r",name);
send_to_char(buf2,ch);
if (history == NULL || history[0] == '\0') {
send_to_char("No pfile history available.\n\r",ch);
} else {
add_buf(output,history);
page_to_char(buf_string(output),ch);
free_buf(output);
}
} else if (arg2[0] != '\0' && !str_prefix(arg2,"equipment")) {
sprintf(buf2,"FINGER: %s's equipment:\n\r(Objects: %d total, %d limited)\n\r\n\r",
name,aobj,lobj);
send_to_char(buf2,ch);
if (eqbuf[0] != '\0')
send_to_char(eqbuf,ch);
else
send_to_char("Nothing.\n\r",ch);
} else if (arg2[0] != '\0' && !str_prefix(arg2,"description")) {
sprintf(buf2,"FINGER: %s's description:\n\r",name);
send_to_char(buf2,ch);
if (desc != NULL)
send_to_char(desc,ch);
else
send_to_char("No description available.\n\r",ch);
} else {
sprintf(buf2,"%sName: %s %s%s\n\r",
dead && IS_SET(act,PLR_DENY) && con < CON_DIE_BOUND ? "*** CON-DEAD CHARACTER: ***\n\r" :
dead && IS_SET(act,PLR_DENY) ? "*** DENIED CHARACTER: ***\n\r" :
dead && died == HAS_DIED ? "*** AGE-DEAD CHARACTER: ***\n\r" :
dead ? "*** DELETED CHARACTER: ***\n\r" : "",
name,title ? title : "",extitle ? extitle : "");
send_to_char(buf2,ch);
sprintf(buf2,"Hours: %d, Age: %d (%s), Death: %d, History: %s\n\r",
played / 3600,
get_age_new(played,race),
get_age_name_new(played,race),
get_death_age_new(race,con,agemod),
history ? "Yes" : "No");
send_to_char(buf2,ch);
sprintf(buf2,"Level: %d, Class: %s, Race: %s, Sex: %s\n\r",
level,class_table[class].name,pc_race_table[race].name,sex);
send_to_char(buf2,ch);
sprintf(buf2,"Cabal: %s%s%s, Align: %s, Ethos: %s\n\r",
(cabal > 0) ? cabal_table[cabal].who_name : "[None]",
empire_table[empire+1].who_name,
induct == CABAL_LEADER || empire >= EMPIRE_SLEADER ? "(Leader)" : "",
align < 0 ? "evil" : align == 0 ? "neutral" : align > 0 ? "good" : "(none)",
ethos < 0 ? "chaotic" : ethos == 0 ? "neutral" : ethos > 0 ? "lawful" : "(none)");
send_to_char(buf2,ch);
sprintf(buf2,"Objs: %d (%d L)\n\r",
aobj,
lobj);
send_to_char(buf2,ch);
sprintf(buf2,"Security: %d.\n\r",security);
send_to_char(buf2,ch);
sprintf(buf2,"PKs: %d (G: %d N: %d E: %d), PKDs: %d, MDs: %d\n\r",
kills, gkills, nkills, ekills, pkilled, mkilled);
send_to_char(buf2,ch);
sprintf(buf2,"Last Login: %s (%d minutes played)\n\r",login,timeplayed);
send_to_char(buf2,ch);
if (allsites) {
allsites = one_argument(allsites, site1);
allsites = one_argument(allsites, site2);
allsites = one_argument(allsites, site3);
allsites = one_argument(allsites, site4);
allsites = one_argument(allsites, site5);
buf2[0] = '\0';
if (site1[0] != '\0') {
strcat(buf2,"Site 1) ");
strcat(buf2,site1);
strcat(buf2,"\n\r");
}
if (site2[0] != '\0') {
strcat(buf2,"Site 2) ");
strcat(buf2,site2);
strcat(buf2,"\n\r");
}
if (site3[0] != '\0') {
strcat(buf2,"Site 3) ");
strcat(buf2,site3);
strcat(buf2,"\n\r");
}
if (site4[0] != '\0') {
strcat(buf2,"Site 4) ");
strcat(buf2,site4);
strcat(buf2,"\n\r");
}
if (site5[0] != '\0') {
strcat(buf2,"Site 5) ");
strcat(buf2,site5);
strcat(buf2,"\n\r");
}
if (buf2[0] != '\0') {
send_to_char(buf2,ch);
}
}
}
return;
}
int count_carried(CHAR_DATA *ch, bool limited)
{
OBJ_DATA *obj;
int count = 0;
for (obj = ch->carrying; obj != NULL; obj = obj->next_content)
{
if (limited && obj->pIndexData->limtotal <= 0)
continue;
count++;
}
return count;
}
void do_otrack( CHAR_DATA *ch, char *argument )
{
extern int top_obj_index;
char buf[MAX_STRING_LENGTH];
char pbuf[MAX_STRING_LENGTH];
char newbuf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
OBJ_INDEX_DATA *pObjIndex=NULL;
int vnum, nMatch, counter;
bool found;
char results[MAX_STRING_LENGTH];
FILE *fpChar;
int numMatches = 0;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Syntax: otrack: <item name>\n\r", ch );
send_to_char( " Tracks the location of an item, even\n\r",ch);
send_to_char( " if the carriers aren't logged on.\n\r",ch);
return;
}
found = FALSE;
nMatch = 0;
if(!is_number(argument))
{
for ( vnum = 0; nMatch < top_obj_index; vnum++ )
{
if ( ( pObjIndex = get_obj_index( vnum ) ) != NULL )
{
nMatch++;
if ( is_name( argument, pObjIndex->name ) )
{
found = TRUE;
break;
}
}
}
}
if(is_number(argument))
{
pObjIndex = get_obj_index( atoi( argument ) );
found = TRUE;
}
if ( !found || !pObjIndex)
{
send_to_char( "No objects by that name found to track.\n\r", ch );
return;
}
buf[0]='\0';
sprintf( buf, "Tracking %s [Vnum %d, Limit is %d, Count is %d]\n\r",
pObjIndex->short_descr, pObjIndex->vnum, pObjIndex->limtotal, pObjIndex->limcount);
send_to_char( buf, ch );
sprintf(pbuf,"grep 'Vnum %d$' %s%s > %s",pObjIndex->vnum,PLAYER_DIR,"*.plr",TEMP_GREP_RESULTS);
system(pbuf);
fpChar=fopen(TEMP_GREP_RESULTS,"r");
if(fpChar==NULL)
{
send_to_char("Error opening results.\n\r",ch);
return;
}
results[0]='\0';
while(fgets(results,200,fpChar))
{
//there are ten chars in ../player/ that we need to get rid of first on the path to getting the name.
newbuf[0]='\0';
for (counter = 0; counter < (strlen(results) - 10);counter++)
{
if(results[counter+10]=='.')
{
newbuf[counter]='\0';
break;
}
newbuf[counter]=results[counter+10];
}
buf[0]='\0';
numMatches++;
sprintf(buf,"%d) %s is carried by %s\n\r",numMatches,pObjIndex->short_descr,newbuf);
send_to_char(buf,ch);
results[0]='\0';
}
fclose(fpChar);
if(!numMatches)
{
buf[0]='\0';
sprintf(buf,"No players currently hold %s.\n\r",pObjIndex->short_descr);
send_to_char(buf,ch);
}
}
void do_ltrack(CHAR_DATA *ch, char *argument)
{
char buf[MAX_STRING_LENGTH];
char pbuf[MAX_STRING_LENGTH];
char results[MAX_STRING_LENGTH];
char temp[MAX_STRING_LENGTH];
char list[2000][110];
char nlist[110];
long size = 0;
FILE *fpChar;
int count, loop;
BUFFER *output;
int numMatches=0;
output = new_buf();
if (!strcmp(argument,""))
{
send_to_char("Syntax: ltrack <name or site>\n\r",ch);
send_to_char(" Searches the logins file for all occurances of given phrase,\n\r",ch);
send_to_char(" whether a character name or site.\n\r",ch);
return;
}
buf[0]='\0';
sprintf( buf, "Searching login records for %s.\n\r",argument);
send_to_char( buf, ch );
sprintf(pbuf,"grep -i -c '%s' %s > %s", argument, LOGIN_LOG_FILE, TEMP_GREP_RESULTS_TWO);
system(pbuf);
sprintf(pbuf,"grep -i '%s' %s > %s", argument, LOGIN_LOG_FILE, TEMP_GREP_RESULTS);
system(pbuf);
fpChar=fopen(TEMP_GREP_RESULTS_TWO,"r");
if(!fpChar)
return;
fscanf(fpChar,"%i",&count);
fclose(fpChar);
fpChar=fopen(TEMP_GREP_RESULTS,"r");
if(fpChar==NULL)
{
send_to_char("Error opening results.\n\r",ch);
return;
}
results[0]='\0';
while(fgets(results,200,fpChar))
{
buf[0]='\0';
temp[0]='\0';
numMatches++;
sprintf(list[numMatches],"%s",results);
if(numMatches>1999)
break;
//If someone has over 2000 logins it won't show the newest ones. Pfft.
}
for(loop=numMatches;loop>=1;loop--)
{
sprintf(nlist,"%3d) %s\r",numMatches+1-loop,list[loop]);
size+=sizeof(nlist);
if(size>=MAX_BUF)
break;
add_buf(output,nlist);
}
sprintf(temp,"%d matching results [displaying first %d matches / %ld bytes]:\n\r",count,(numMatches-loop),size);
send_to_char(temp,ch);
page_to_char(buf_string(output),ch);
free_buf(output);
if(count==0)
send_to_char("No matching records were found.\n\r",ch);
fclose(fpChar);
}
void do_pload (CHAR_DATA *ch,char *argument)
{
DESCRIPTOR_DATA *d;
char name[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
argument = one_argument(argument,name);
if (name[0] == '\0' || argument[0] == '\0')
{
send_to_char("Syntax: pload <char> <command>\n\r",ch);
return;
}
name[0] = UPPER(name[0]);
if (get_char_world(ch,name) != NULL)
{
send_to_char("That character is already online!\n\r",ch);
return;
}
d = new_descriptor();
if (!load_char_obj(d,name))
{
send_to_char("No such character exists.\n\r",ch);
return;
}
sprintf(buf,"cp %s%s%s %spload.txt",PLAYER_DIR,name,".plr",PLAYER_DIR);
system(buf);
d->character->desc = NULL;
d->character->next = char_list;
char_list = d->character;
d->connected = CON_PLAYING;
d->outsize = 2000;
d->outbuf = alloc_mem(d->outsize);
reset_char(d->character);
victim = d->character;
interpret(ch,argument);
sprintf(buf,"%s%s%s",PLAYER_DIR,name,".plr");
if (fopen(buf, "r") != NULL)
{
save_char_obj(victim);
extract_char(victim, TRUE);
}
free_descriptor(d);
return;
}
int get_spell_aftype(CHAR_DATA *ch)
{
if (class_table[ch->class].ctype == CLASS_COMMUNER)
{
return AFT_COMMUNE;
} else {
return AFT_SPELL;
}
return -1;
}
void do_sing( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
OBJ_DATA *obj;
OBJ_DATA *instrument;
void *vo;
int mana;
int sn;
int target;
int success_chance;
if(is_affected(ch,gsn_tigerclaw))
{
send_to_char("Your throat constricts too painfully.\n\r",ch);
return;
}
if (is_affected(ch, gsn_gag) && number_percent()<90)
{
send_to_char("You nearly choke on the cloth in your mouth as you attempt to sing...\n\r",ch);
act("$N raises his chin as if to sing, but begins to choke on something.",ch,NULL,NULL,TO_ROOM);
return;
}
if ( IS_NPC(ch) && ch->desc == NULL)
return;
target_name = one_argument( argument, arg1 );
one_argument( target_name, arg2 );
if ( arg1[0] == '\0' )
return send_to_char( "Sing which what where?\n\r", ch );
if ((sn = find_spell(ch,arg1)) < 1
|| skill_table[sn].spell_fun == spell_null
|| (!IS_NPC(ch) && get_skill(ch,sn) < 5)
|| (!IS_NPC(ch) && ch->pcdata->learned[sn] == 0))
return send_to_char( "You don't know any sings of that name.\n\r", ch );
if ( ch->position < skill_table[sn].minimum_position && get_trust(ch)<MAX_LEVEL-1)
return send_to_char( "You can't concentrate enough.\n\r", ch );
if(skill_table[sn].ctype!=CMD_SONG && !IS_IMMORTAL(ch))
return send_to_char("You can't sing that.\n\r",ch);
if (ch->level + 2 == skill_table[sn].skill_level[ch->class])
mana = 50;
else
mana = UMAX(
skill_table[sn].min_mana,
100 / ( 2 + ch->level - skill_table[sn].skill_level[ch->class] ) );
{
}
/*
* Locate targets.
*/
victim = NULL;
obj = NULL;
vo = NULL;
target = TARGET_NONE;
switch ( skill_table[sn].target )
{
default:
bug( "Do_sing: bad target for sn %d.", sn );
return;
case TAR_IGNORE:
break;
case TAR_CHAR_OFFENSIVE:
if ( arg2[0] == '\0' )
{
if ( ( victim = ch->fighting ) == NULL )
return send_to_char( "Sing the song on whom?\n\r", ch );
}
else
{
if ( ( victim = get_char_room( ch, target_name ) ) == NULL )
return send_to_char( "They aren't here.\n\r", ch );
}
if ( !IS_NPC(ch) )
check_killer(ch,victim);
vo = (void *) victim;
target = TARGET_CHAR;
break;
case TAR_CHAR_DEFENSIVE:
if ( arg2[0] == '\0' )
victim = ch;
else
{
if ( ( victim = get_char_room( ch, target_name ) ) == NULL )
return send_to_char( "They aren't here.\n\r", ch );
}
vo = (void *) victim;
target = TARGET_CHAR;
break;
case TAR_CHAR_SELF:
if ( arg2[0] != '\0' && !is_name( target_name, ch->name ) )
return send_to_char( "You cannot sing this song on another.\n\r", ch );
vo = (void *) ch;
target = TARGET_CHAR;
break;
case TAR_OBJ_INV:
if ( arg2[0] == '\0' )
return send_to_char( "What should the song be called upon?\n\r", ch );
if ( ( obj = get_obj_carry( ch, target_name, ch ) ) == NULL )
return send_to_char( "You are not carrying that.\n\r", ch );
vo = (void *) obj;
target = TARGET_OBJ;
break;
case TAR_OBJ_CHAR_OFF:
if (arg2[0] == '\0')
{
if ((victim = ch->fighting) == NULL)
return send_to_char("Sing the song on who or what?\n\r",ch);
target = TARGET_CHAR;
}
else if ((victim = get_char_room(ch,target_name)) != NULL)
{
target = TARGET_CHAR;
}
if (target == TARGET_CHAR) /* check the sanity of the attack */
{
if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim )
return send_to_char( "You can't do that on your own follower.\n\r", ch );
if (!IS_NPC(ch))
check_killer(ch,victim);
vo = (void *) victim;
}
else if ((obj = get_obj_here(ch,target_name)) != NULL)
{
vo = (void *) obj;
target = TARGET_OBJ;
}
else
return send_to_char("You don't see that here.\n\r",ch);
break;
case TAR_OBJ_CHAR_DEF:
if (arg2[0] == '\0')
{
vo = (void *) ch;
target = TARGET_CHAR;
}
else if ((victim = get_char_room(ch,target_name)) != NULL)
{
vo = (void *) victim;
target = TARGET_CHAR;
}
else if ((obj = get_obj_carry(ch,target_name,ch)) != NULL)
{
vo = (void *) obj;
target = TARGET_OBJ;
}
else
return send_to_char("You don't see that here.\n\r",ch);
break;
}
if ( !IS_NPC(ch) && ch->mana < mana )
return send_to_char( "You don't have enough mana.\n\r", ch );
success_chance = get_skill(ch,sn);
instrument = get_eq_char(ch, WEAR_HOLD);
if (instrument == NULL || instrument->item_type != ITEM_INSTRUMENT)
{
success_chance /= 1.25;
}
if (is_affected(ch,gsn_deafen))
{
success_chance /= 4;
}
WAIT_STATE( ch, skill_table[sn].beats );
if ( !IS_NPC(ch) && (number_percent( ) > success_chance))
{
if (instrument == NULL || instrument->item_type != ITEM_INSTRUMENT)
{
act("$n tries to remain in tune without an instrument but fails horribly.",ch,NULL,NULL,TO_ROOM);
send_to_char("You try to remain in tune without an instrument but fail horribly.\n\r",ch);
}
else if (is_affected(ch,gsn_deafen))
{
act("$n tries to remain in tune even without hearing $s own voice.",ch,NULL,NULL,TO_ROOM);
send_to_char("You try to remain in tune even without hearing your own voice.\n\r",ch);
}
else
{
act("$n's fingers slip and the song ends abruptly.",ch,NULL,NULL,TO_ROOM);
send_to_char("Your fingers slip and the song ends abruptly.\n\r",ch);
}
check_improve(ch,sn,FALSE,1);
ch->mana -= mana / 2;
}
else
{
if (instrument == NULL || instrument->item_type != ITEM_INSTRUMENT)
{
act("$n begins to sing acapella.",ch,NULL,NULL,TO_ROOM);
send_to_char("You begin to sing acapella.\n\r",ch);
}
else if (is_affected(ch,gsn_deafen))
{
act("$n tries to remain in tune even without hearing $s own voice.",ch,NULL,NULL,TO_ROOM);
send_to_char("You try to remain in tune even without hearing your own voice.\n\r",ch);
}
else
{
act("$n begins to sing while playing a melody on $p.",ch,instrument,NULL,TO_ROOM);
act("You begin to sing while playing a melody on $p.",ch,instrument,NULL,TO_CHAR);
}
ch->mana -= mana;
if (skill_table[sn].target == TAR_CHAR_OFFENSIVE
&& is_safe(ch,victim))
return;
if (skill_table[sn].target == TAR_CHAR_OFFENSIVE)
{
if (!IS_NPC(ch) && !IS_NPC(victim)
&& (ch->fighting == NULL || victim->fighting == NULL))
{
switch(number_range(0,2))
{
case (0):
case (1):
sprintf(buf,"Die, %s you filthy dog!",PERS(ch,victim));
break;
case (2):
sprintf(buf,"Help! %s is attacking me!",PERS(ch,victim));
}
if (victim != ch && !IS_NPC(ch))
do_myell(victim,buf);
}
}
(*skill_table[sn].spell_fun) ( sn, ch->level, ch, vo,target);
check_improve(ch,sn,TRUE,1);
}
if ((skill_table[sn].target == TAR_CHAR_OFFENSIVE
|| (skill_table[sn].target == TAR_OBJ_CHAR_OFF && target == TARGET_CHAR))
&& victim != ch
&& victim->master != ch)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
for ( vch = ch->in_room->people; vch; vch = vch_next )
{
vch_next = vch->next_in_room;
if ( victim == vch && victim->fighting == NULL )
{ check_killer(victim,ch);
multi_hit( victim, ch, TYPE_UNDEFINED );
break;
}
}
}
return;
}
void do_rehearsal( CHAR_DATA *ch, char *argument )
{
BUFFER *buffer;
char arg[MAX_INPUT_LENGTH];
char spell_list[LEVEL_HERO + 1][MAX_STRING_LENGTH];
char spell_columns[LEVEL_HERO + 1];
int sn, level, min_lev = 1, max_lev = LEVEL_HERO, mana;
bool fAll = FALSE, found = FALSE;
char buf[MAX_STRING_LENGTH];
if (IS_NPC(ch))
return;
if(class_table[ch->class].ctype!=CLASS_SING && !IS_IMMORTAL(ch))
{
send_to_char("Your class knows no prayers.\n\r",ch);
}
if (argument[0] != '\0')
{
fAll = TRUE;
if (str_prefix(argument,"all"))
{
argument = one_argument(argument,arg);
if (!is_number(arg))
{
send_to_char("Arguments must be numerical or all.\n\r",ch);
return;
}
max_lev = atoi(arg);
if (max_lev < 1 || max_lev > LEVEL_HERO)
{
sprintf(buf,"Levels must be between 1 and %d.\n\r",LEVEL_HERO);
send_to_char(buf,ch);
return;
}
if (argument[0] != '\0')
{
argument = one_argument(argument,arg);
if (!is_number(arg))
{
send_to_char("Arguments must be numerical or all.\n\r",ch);
return;
}
min_lev = max_lev;
max_lev = atoi(arg);
if (max_lev < 1 || max_lev > LEVEL_HERO)
{
sprintf(buf,
"Levels must be between 1 and %d.\n\r",LEVEL_HERO);
send_to_char(buf,ch);
return;
}
if (min_lev > max_lev)
{
send_to_char("That would be silly.\n\r",ch);
return;
}
}
}
}
/* initialize data */
for (level = 0; level < LEVEL_HERO + 1; level++)
{
spell_columns[level] = 0;
spell_list[level][0] = '\0';
}
for (sn = 0; sn < MAX_SKILL; sn++)
{
if (skill_table[sn].name == NULL )
break;
if ((level = skill_table[sn].skill_level[ch->class]) < LEVEL_HERO + 1
&& level >= min_lev && level <= max_lev
&& skill_table[sn].spell_fun != spell_null
&& ch->pcdata->learned[sn] > 0
&& (skill_table[sn].ctype==CMD_SONG))
{
found = TRUE;
level = skill_table[sn].skill_level[ch->class];
if (ch->level < level)
sprintf(buf,"%-18s n/a ", skill_table[sn].name);
else
{
mana = UMAX(skill_table[sn].min_mana,
100/(2 + ch->level - level));
sprintf(buf,"%-18s %3d mana ",skill_table[sn].name,mana);
}
if (spell_list[level][0] == '\0')
sprintf(spell_list[level],"\n\rLevel %2d: %s",level,buf);
else /* append */
{
if ( ++spell_columns[level] % 2 == 0)
strcat(spell_list[level],"\n\r ");
strcat(spell_list[level],buf);
}
}
}
/* return results */
if (!found)
{
send_to_char("No songs found.\n\r",ch);
return;
}
buffer = new_buf();
for (level = 0; level < LEVEL_HERO + 1; level++)
if (spell_list[level][0] != '\0')
add_buf(buffer,spell_list[level]);
add_buf(buffer,"\n\r");
page_to_char(buf_string(buffer),ch);
free_buf(buffer);
}
void do_assess(CHAR_DATA *ch, char *argument)
{
int skill, fuzzy, showdur;
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
char buf[MAX_STRING_LENGTH];
AFFECT_DATA *paf;
one_argument(argument,arg);
if(argument[0]=='\0')
{
send_to_char("Syntax: assess <target>\n\r",ch);
return;
}
if((skill=get_skill(ch,skill_lookup("assess")))<5)
{
send_to_char("You don't know how to assess people's conditions.\n\r",ch);
return;
}
if ((victim = get_char_room(ch,arg)) == NULL)
{
send_to_char("They aren't here.\n\r",ch);
return;
}
if(victim==ch)
{
send_to_char("Why not just use affects?\n\r",ch);
return;
}
act("You study $N intently, searching for signs of affliction.",ch,0,victim,TO_CHAR);
if(number_percent()>skill)
{
send_to_char("You lose your concentration before finding any telltale signs of affliction.\n\r",ch);
check_improve(ch,skill_lookup("assess"),FALSE,1);
WAIT_STATE(ch,PULSE_VIOLENCE);
ch->mana-=20;
return;
}
if(victim->affected==NULL)
{
send_to_char("You are unable to find any signs of affliction.\n\r",ch);
check_improve(ch,skill_lookup("assess"),TRUE,1);
WAIT_STATE(ch,PULSE_VIOLENCE);
ch->mana-=40;
return;
}
for ( paf = victim->affected; paf != NULL; paf = paf->next )
{
buf[0]='\0';
if(skill<91);
sprintf(buf,"%s seems to be affected by %s.\n\r",IS_NPC(victim) ? victim->short_descr : victim->name,skill_table[paf->type].name);
if(skill>=91);
{
fuzzy=number_range(0,2);
//Let's fuz up the duration a bit if it's not permanent.
if(paf->duration>-1)
{
if(number_range(0,1)==0)
showdur=paf->duration+fuzzy;
else
showdur=paf->duration-fuzzy;
sprintf(buf,"%s seems to be affected by %s for about %d hours.\n\r",IS_NPC(victim) ? victim->short_descr : victim->name,skill_table[paf->type].name,showdur);
}
if(paf->duration==-1)
sprintf(buf,"%s seems to be affected by %s permanently.\n\r",IS_NPC(victim) ? victim->short_descr : victim->name,skill_table[paf->type].name);
}
send_to_char(buf,ch);
}
check_improve(ch,skill_lookup("assess"),TRUE,1);
WAIT_STATE(ch,PULSE_VIOLENCE);
ch->mana-=40;
}
void do_piethrow( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
int chance;
char buf[MAX_STRING_LENGTH];
one_argument(argument,arg);
if ( (chance = get_skill(ch,gsn_pie)) == 0
|| (IS_NPC(ch) && ch->pIndexData->vnum!=MOB_VNUM_TEMPLAR)
|| (!IS_NPC(ch)
&& ch->level < skill_table[gsn_pie].skill_level[ch->class]))
{
send_to_char("You don't know how to do that.\n\r",ch);
return;
}
if (arg[0] == '\0')
{
victim = ch->fighting;
if (victim == NULL)
{
send_to_char("But you aren't in combat!\n\r",ch);
return;
}
}
else if ((victim = get_char_room(ch,arg)) == NULL)
{
send_to_char("They aren't here.\n\r",ch);
return;
}
if (IS_AFFECTED(victim,AFF_BLIND))
{
act("$E's already been blinded.",ch,NULL,victim,TO_CHAR);
return;
}
if(victim->position==POS_SLEEPING) {
send_to_char("It wouldnt be funny while they are sleeping!\n\r",ch);
return;
}
if (victim == ch)
{
send_to_char("Very funny.\n\r",ch);
return;
}
if (is_safe(ch,victim))
return;
if (IS_AFFECTED(ch,AFF_CHARM) && ch->master == victim)
{
act("But $N is such a good friend!",ch,NULL,victim,TO_CHAR);
return;
}
/* modifiers */
/* dexterity */
chance += get_curr_stat(ch,STAT_DEX);
chance -= 2 * get_curr_stat(victim,STAT_DEX);
/* speed */
if (IS_SET(ch->off_flags,OFF_FAST) || is_affected(ch,skill_lookup("haste")))
chance += 10;
if (IS_SET(victim->off_flags,OFF_FAST) || is_affected(victim,skill_lookup("haste")))
chance -= 30;
/* level */
chance += (ch->drain_level + ch->level - victim->level - victim->drain_level) * 2;
/* sloppy hack to prevent false zeroes */
if (chance % 5 == 0)
chance += 1;
/* now the attack */
if (number_percent() < chance)
{
AFFECT_DATA af;
act("$n is blinded by the pie in $s eyes!",victim,NULL,NULL,TO_ROOM);
act("$n throws a pie right in your face",ch,NULL,victim,TO_VICT);
if (!IS_NPC(ch) && !IS_NPC(victim) &&
( (victim->fighting == NULL) || (ch->fighting == NULL)))
do_myell(victim,"Help! Someone just through a pie at my face!");
damage(ch,victim,number_range(10,20),gsn_pie,DAM_NONE,TRUE);
send_to_char("You can't see a thing!\n\r",victim);
check_improve(ch,gsn_pie,TRUE,2);
WAIT_STATE(ch,skill_table[gsn_pie].beats);
init_affect(&af);
af.where = TO_AFFECTS;
af.type = gsn_pie;
af.aftype = AFT_SKILL;
af.level = ch->level + ch->drain_level;
af.duration = 0;
af.location = APPLY_HITROLL;
af.modifier = -4;
af.bitvector = AFF_BLIND;
affect_to_char(victim,&af);
}
else
{
if (!IS_NPC(ch) && !IS_NPC(victim)
&& (victim->fighting == NULL || ch->fighting == NULL))
{
switch(number_range(0,1))
{
case (0):
sprintf(buf,"Help! %s just tried to throw a pie at me!",PERS(ch,victim));
break;
case (1):
sprintf(buf,"Die, %s you pie-throwing fool!",PERS(ch,victim));
break;
}
do_myell(victim,buf);
}
damage(ch,victim,0,gsn_pie,DAM_NONE,TRUE);
check_improve(ch,gsn_pie,FALSE,2);
WAIT_STATE(ch,skill_table[gsn_pie].beats);
}
check_killer(ch,victim);
}