/****************************************************************************
* 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. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. 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. *
****************************************************************************/
/****************************************************************************
* ROM 2.4 is copyright 1993-1998 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@hypercube.org) *
* Gabrielle Taylor (gtaylor@hypercube.org) *
* Brian Moore (zump@rom.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
****************************************************************************/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include "merc.h"
#include "interp.h"
#include "clans/new_clans.h"
#include "clans/new_clans_comm.h"
#include "clans/new_clans_io.h"
#include "clans/new_clans_util.h"
#include "obj_trig.h"
//Iblis - Created 9/29/04 to hold all of the Chaos Jester class skills
/*OBJ_DATA *get_obj_vnum_room args((ROOM_INDEX_DATA* rid, int vnum));
OBJ_DATA *get_obj_vnum_char args((CHAR_DATA* ch, int vnum));
void affect_strip_skills args((CHAR_DATA * ch));
long int level_cost args ((int level));
extern int arearooms args ((CHAR_DATA * ch));
extern int areacount args ((CHAR_DATA * ch));
extern int roomcount args ((CHAR_DATA * ch));*/
int quiver_holding args((OBJ_DATA * obj));
void save_player_box args((OBJ_DATA * pObj));
void show_list_to_char args ((OBJ_DATA * list, CHAR_DATA * ch, bool fShort, bool fShowNothing));
bool can_move_char args ((CHAR_DATA * ch, ROOM_INDEX_DATA * to_room, bool follow, bool show_messages));
void one_hit args ((CHAR_DATA * ch, CHAR_DATA * victim, int dt));
void prevent_escape args ((CHAR_DATA * ch, CHAR_DATA * victim));
int check_entangle args ((CHAR_DATA * ch));
bool check_clasp args((CHAR_DATA *ch));
void one_hit_throw args((CHAR_DATA * ch, CHAR_DATA * victim, int dt, OBJ_DATA * wield));
CHAR_DATA *get_gravity_char_room args((ROOM_INDEX_DATA *rid));
void flick_card args((CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj, int sn));
void friend_poof args((CHAR_DATA *ch));
bool check_flicker (CHAR_DATA * ch, CHAR_DATA * victim)
{
int chance;
if (!IS_AWAKE (victim))
return FALSE;
chance = get_skill (victim, gsn_flicker) / 2;
if (!can_see (victim, ch))
{
if (number_percent () < get_skill (victim, gsn_blindfighting))
check_improve (victim, gsn_blindfighting, TRUE, 2);
else
{
check_improve (victim, gsn_blindfighting, FALSE, 2);
chance /= 2;
}
}
// Minax 12-20-02 Dodge depends on skill, not level
// if (number_percent () >= chance + victim->level - ch->level)
if (number_percent () >= chance)
return FALSE;
act ("$N flickers out of reality and your weapon passes right through $M.", ch, NULL, victim, TO_CHAR);
act ("You flicker right out of reality as $n swings at you.", ch, NULL, victim, TO_VICT);
check_improve (victim, gsn_flicker, TRUE, 6);
return TRUE;
}
//Warp touch skill
void do_warptouch (CHAR_DATA *ch, char *argument)
{
int chance;
CHAR_DATA *victim;
if ((chance = get_skill(ch,gsn_warp_touch)) < 1)
{
send_to_char("Warp speed ahead!\n\r",ch);
return;
}
if (argument[0] == '\0')
{
send_to_char("Warptouch whom?\n\r",ch);
return;
/* victim = ch->fighting;dd
if (victim == NULL)
{
send_to_char ("But you aren't fighting anyone!\n\r", ch);
return;
}*/
}
if ((victim = get_char_room (ch, argument)) == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
if (is_safe (ch, victim))
return;
if (ch == victim)
{
send_to_char("When you think about you, you touch yourself.\n\r",ch);
return;
}
if (IS_AFFECTED (ch, AFF_CHARM) && ch->master == victim)
{
act ("But $N is your friend!", ch, NULL, victim, TO_CHAR);
return;
}
if (IS_AFFECTED (ch, AFF_CALM) || is_affected (ch, skill_lookup
("Quiet Mountain Lake")))
{
send_to_char ("You are feeling too peaceful to do that now.\n\r", ch);
return;
}
if (ch->position < POS_FIGHTING)
{
send_to_char("Get off your ass, doofus!\n\r",ch);
return;
}
if (ch->fighting != NULL)
{
send_to_char("No way! You are still fighting!\n\r",ch);
return;
}
/*if (ch->hit < 15)
{
send_to_char("You do not have enough within you to create a spear.\n\r",ch);
return;
}
else ch->hit -= 15;*/
if (chance > number_percent ())
{
send_to_char("Your hand sizzles with tickling energy that makes you giggle to yourself.\n\r",ch);
act("You slap $N in the face, sending $M to the ground.",ch,NULL,victim,TO_CHAR);
act("Sizzling energy courses through your spasming body as $n touches you!",ch,NULL,victim,TO_VICT);
act("Red and yellow light explodes as $n touches $N!",ch,NULL,victim,TO_NOTVICT);
damage (ch, victim, adjust_damage(ch->damroll+(ch->perm_stat[STAT_STR]*2)), gsn_warp_touch, number_range(1,DAM_WIND), TRUE);
}
else
{
send_to_char("Your hand sizzles with tickling energy that makes you giggle to yourself.\n\r",ch);
act("You attempt to slap $N in the face, miss $m completely.",ch,NULL,victim,TO_CHAR);
act("$n's hand comes out in an attempt to slap you in the face, but $e misses completely.",ch,NULL,victim,TO_VICT);
act("$n's hand comes out in an attempt to slap $N in the face, but $e misses completely.",ch,NULL,victim,TO_NOTVICT);
damage (ch, victim, 0, gsn_warp_touch, number_range(1,DAM_WIND), TRUE);
}
}
void do_madrush (CHAR_DATA *ch, char *argument)
{
int chance, dam;
short s1=0;
CHAR_DATA *victim;
if ((chance = get_skill(ch,gsn_mad_rush)) < 1)
{
send_to_char("You rush forward like mad!\n\r",ch);
return;
}
if (argument[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, argument)) == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
if (is_safe (ch, victim))
return;
if (ch == victim)
{
send_to_char("You make a mad rush at yourself, but collapse in a heap.\n\r",ch);
return;
}
if (IS_AFFECTED (ch, AFF_CHARM) && ch->master == victim)
{
act ("But $N is your friend!", ch, NULL, victim, TO_CHAR);
return;
}
if (IS_AFFECTED (ch, AFF_CALM) || is_affected (ch, skill_lookup
("Quiet Mountain Lake")))
{
send_to_char ("You are feeling too peaceful to do that now.\n\r", ch);
return;
}
s1=100*(ch->hit/(ch->max_hit*1.0));
if (ch->move < s1)
{
send_to_char("The only sort of rushing you have the energy to do is towards bed.\n\r",ch);
return;
}
else ch->move -= s1;
WAIT_STATE (ch, skill_table[gsn_mad_rush].beats);
if (chance > number_percent ())
{
act("Having nothing better to do, you rush headfirst into $N.",ch,NULL,victim,TO_CHAR);
act("Suddenly $n decides to run into you!",ch,NULL,victim,TO_VICT);
act("$n runs and crashes headfirst into $N!",ch,NULL,victim,TO_NOTVICT);
dam = ch->max_hit/10.0;
dam = 150 + ((10 - ch->hit/dam)*10.0);
damage (ch, victim, adjust_damage(dam), gsn_mad_rush, DAM_BASH, TRUE);
return;
}
else
{
act("Having nothing better to do, you rush headfirst into $N.",ch,NULL,victim,TO_CHAR);
send_to_char("You fall flat on your face!\n\r",ch);
act("$n falls flat on $s face!",ch,NULL,victim,TO_ROOM);
/*
act("You summon your strength to form a spear made of pure ice and throw it at $N.",ch,NULL,victim,TO_CHAR);
act("$n seems to get a little shorter as $e forms a spear of ice and throw it at $N.",ch,NULL,victim,TO_NOTVICT);
act("$n seems to get a little shorter as $e forms a spear of ice and throw it at you.",ch,NULL,victim,TO_VICT);*/
damage (ch, victim, 0, gsn_mad_rush, DAM_BASH, FALSE);
ch->position = POS_RESTING;
if (IS_NPC (ch))
ch->color = 42;
return;
}
}
void do_coma (CHAR_DATA * ch, char *argument)
{
int chance;
if ((chance = get_skill(ch,gsn_coma)) < 1)
{
send_to_char("You can only get that from a hit on the head.",ch);
return;
}
if (ch->race == PC_RACE_SWARM)
{
send_to_char("Huh?\n\r",ch);
return;
}
if (is_affected (ch, skill_lookup ("Dance of Shadows")))
{
send_to_char ("Your nightmares keep you from slipping into a coma.\n\r", ch);
return;
}
if (is_affected (ch, gsn_fear))
{
send_to_char ("You are WAY too scared to slip into a coma right now!\n\r",ch);
return;
}
if (ch->fighting != NULL)
{
send_to_char ("You are WAY too busy to slip into a coma now!\n\r", ch);
return;
}
if (chance > number_percent())
{
switch (ch->position)
{
case POS_SLEEPING:
send_to_char ("You are already sleeping.\n\r", ch);
break;
case POS_MOUNTED:
send_to_char ("You must dismount before you can slip into a coma.\n\r", ch);
return;
case POS_RESTING:
case POS_SITTING:
case POS_STANDING:
send_to_char ("You slip into a coma.\n\r", ch);
act ("$n lies down and stops breathing completely.", ch, NULL, NULL, TO_ROOM);
ch->position = POS_COMA;
trip_triggers(ch, OBJ_TRIG_CHAR_POS_CHANGE, NULL, NULL, OT_SPEC_NONE);
ch->on = NULL; //Can't go comatose on any object
break;
case POS_FIGHTING:
send_to_char ("You are WAY too busy to slip into a coma now!\n\r", ch);
break;
}
} else
send_to_char ("One of the voices incessant yapping prevents you from doing so.\n\r",ch);
return;
}
//Iblis - Vanish skill
void do_vanish (CHAR_DATA *ch, char *argument)
{
AFFECT_DATA af;
int chance;
if ((chance = get_skill(ch,gsn_vanish)) < 1)
{
send_to_char("You close your eyes and the world vanishes!\n\r",ch);
return;
}
if (ch->move < 100)
{
send_to_char("You cannot muster the strength to vanish.\n\r",ch);
return;
}
else ch->move -= ch->move*.95;
if (IS_AFFECTED (ch, AFF_INVISIBLE))
{
send_to_char ("Your are already invisible.\n\r", ch);
return;
}
if (chance > number_percent())
{
af.where = TO_AFFECTS;
af.type = gsn_vanish;
af.level = ch->level;
af.duration = 40 + ch->perm_stat[STAT_WIS];
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_INVISIBLE;
af.permaff = FALSE;
af.composition = FALSE;
af.comp_name = str_dup ("");
affect_to_char (ch, &af);
send_to_char("You slap your hands across your eyes and pretend that you are invisible.\n\r",ch);
act ("$n crawls into $s navel and vanishes!",ch,NULL,NULL,TO_ROOM);
WAIT_STATE (ch, skill_table[gsn_vanish].beats);
return;
}
WAIT_STATE (ch, skill_table[gsn_vanish].beats);
send_to_char("You slap your hands across your eyes, but you can't help peeking so it does no good.\n\r",ch);
}
void do_persuade (CHAR_DATA *ch, char *argument)
{
int chance, amount,amount2;
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
if ((chance = get_skill(ch,gsn_persuade)) < 1)
{
send_to_char("You couldn't persuade a starving man to eat.\n\r",ch);
return;
}
if ((victim = get_char_room (ch, argument)) == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
if (is_safe (ch, victim))
return;
if (chance > number_percent() && get_curr_stat(ch,STAT_CHA) > get_curr_stat(victim,STAT_CHA))
{
act("You persuade $N to give you the money that should have been yours in the first place.",ch,NULL,victim,TO_CHAR);
if (ch->race != PC_RACE_SIDHE && ch->race != PC_RACE_LITAN)
{
switch (number_range(1,8))
{
case 1: do_say(ch,"Give me your money because: I deserve to be rich");break;
case 2: do_say(ch,"Give me your money because: I need them");break;
case 3: do_say(ch,"Give me your money because: I'm such a nice person");break;
case 4: do_say(ch,"Give me your money because: I'm better than you");break;
case 5: do_say(ch,"Give me your money, or else!");break;
case 6: do_say(ch,"Some extra money would be nice right about now");break;
case 7: do_say(ch,"I'm here to collect the tax for king Athanmere");break;
case 8: do_say(ch,"You owe me money. You know, from that time at the place?");break;
}
}
act("$n persuades $N to give $m money.",ch,NULL,victim,TO_NOTVICT);
WAIT_STATE(ch,skill_table[gsn_persuade].beats);
if (get_curr_stat(ch,STAT_CHA) > 10)
chance = number_range(10,get_curr_stat(ch,STAT_CHA));
else chance = number_range(get_curr_stat(ch,STAT_CHA),10);
amount = victim->silver * (chance/100.0);
ch->silver += amount;
victim->silver -= amount;
amount2 = victim->gold * (chance/100.0);
ch->gold += amount2;
victim->gold -= amount2;
sprintf(buf,"You give $n %d gold and %d silver.",amount2,amount);
act(buf,ch,NULL,victim,TO_VICT);
}
else
{
act("You try to persuade $N to give you money but you don't do that by slapping them in the face.",ch,NULL,victim,TO_CHAR);
act("$n slaps you in the face, and you don't take it very well.",ch,NULL,victim,TO_VICT);
act("$n slaps $N in the face.",ch,NULL,victim,TO_NOTVICT);
damage(ch,victim,0,gsn_persuade,DAM_UNIQUE,FALSE);
WAIT_STATE(ch,skill_table[gsn_persuade].beats);
}
}
//Iblis - Mad Dance skill
void do_maddance (CHAR_DATA *ch, char *argument)
{
AFFECT_DATA af;
int chance;
// CHAR_DATA *victim;
if ((chance = get_skill(ch,gsn_mad_dance)) < 1)
{
send_to_char("You dances like a madman, but only succeed in making people think you're mad.\n\r",ch);
return;
}
if (is_affected(ch,skill_lookup("spider body")))
{
send_to_char("Spiders can't dance. Spiders can't walk. The only thing about them is the way they talk.\n\r",ch);
return;
}
if (ch->mana < ch->max_mana*.25 || ch->move < ch->max_move*((80 - ch->perm_stat[STAT_CON])/100.0) || ch->move < ch->max_move*.50)
{
send_to_char("You are too exhausted to dance.\n\r",ch);
return;
}
ch->mana -= ch->max_mana*.25;
ch->move -= ch->max_move*((80 - ch->perm_stat[STAT_CON])/100.0);
if (is_affected (ch, gsn_mad_dance))
{
send_to_char ("Your are already affected by a mad dance.\n\r", ch);
return;
}
if (chance > number_percent())
{
af.where = TO_SKILL;
af.type = gsn_mad_dance;
af.level = ch->level;
af.duration = ch->perm_stat[STAT_DEX];
af.location = gsn_second_attack;
af.modifier = 100;
af.bitvector = 0;
af.permaff = FALSE;
af.composition = FALSE;
af.comp_name = str_dup ("");
affect_to_char (ch, &af);
af.location = gsn_third_attack;
affect_to_char(ch, &af);
send_to_char("You start dancing and notice the envious stares of everyone else.\n\r",ch);
act("You look at $n incredulously as $e starts dancing like a madman with two left feet.",ch,NULL,NULL,TO_ROOM);
WAIT_STATE (ch, skill_table[gsn_mad_dance].beats);
return;
}
WAIT_STATE (ch, skill_table[gsn_mad_dance].beats);
send_to_char("You start dancing, but after kicking yourself in the ass a few times you stop.\n\r",ch);
act("You look at $n incredulously as $e starts kicking $mself in the ass.",ch,NULL,NULL,TO_ROOM);
}
//Iblis - Fire Dance skill
void do_firedance (CHAR_DATA *ch, char *argument)
{
AFFECT_DATA af;
int chance;
// CHAR_DATA *victim;
if ((chance = get_skill(ch,gsn_fire_dance)) < 1)
{
send_to_char("You dances fast and furiously, but the only thing on fire is people's feet as they run quickly away.\n\r",ch);
return;
}
if (is_affected(ch,skill_lookup("spider body")))
{
send_to_char("Spiders can't dance. Spiders can't walk. The only thing about them is the way they talk.\n\r",ch);
return;
}
if (ch->mana < ch->max_mana*.30 || ch->move < ch->max_move*((50 - ch->perm_stat[STAT_CON])/100.0) || ch->move < ch->max_move*.50)
{
send_to_char("You are too exhausted to dance.\n\r",ch);
return;
}
ch->mana -= ch->max_mana*.30;
ch->move -= ch->max_move*((50 - ch->perm_stat[STAT_CON])/100.0);
if (is_affected (ch, gsn_fire_dance))
{
send_to_char ("Your are already affected by a fire dance.\n\r", ch);
return;
}
if (chance > number_percent())
{
af.where = TO_AFFECTS;
af.type = gsn_fire_dance;
af.level = ch->level;
af.duration = ch->perm_stat[STAT_DEX];
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = 0;
af.permaff = FALSE;
af.composition = FALSE;
af.comp_name = str_dup ("");
affect_to_char (ch, &af);
send_to_char("As you start dancing, multicolored flames envelop your hands.\n\r",ch);
act("As $n starts dancing, $s hands light up with multicolored fire!",ch,NULL,NULL,TO_ROOM);
WAIT_STATE (ch, skill_table[gsn_fire_dance].beats);
return;
}
WAIT_STATE (ch, skill_table[gsn_fire_dance].beats);
send_to_char("You start dancing, and your ass catches on fire! You shake your booty until it stops.\n\r",ch);
act("You look at $n incredulously as smoke starts coming from $s ass.",ch,NULL,NULL,TO_ROOM);
}
void do_escape (CHAR_DATA *ch, char *argument)
{
ROOM_INDEX_DATA *pRoomIndex;
int chance, counter=0;
if ((chance = get_skill(ch,gsn_escape)) < 1 || ch->fighting == NULL)
{
send_to_char("You escape into the world you currently exist.\n\r",ch);
return;
}
if (!is_affected(ch,skill_lookup("spider body")))
{
send_to_char("You don't have enough legs to escape!\n\r",ch);
return;
}
if (ch->hit < 60 - ch->perm_stat[STAT_CON])
{
send_to_char("You can't pull off an escape and live.\n\r",ch);
return;
}
if (ch->position < POS_FIGHTING)
{
send_to_char("You need to escape your ass from the ground first.\n\r",ch);
return;
}
if (is_affected(ch,skill_lookup("demonic possession")))
{
send_to_char("The demonic being inside you does not want to flee.\n\r",ch);
return;
}
if (!check_web (ch))
return;
if (!check_entangle (ch))
return;
if (!check_clasp (ch))
return;
if (((!IS_NPC (ch->fighting) && ch->fighting->pcdata->prevent_escape)
|| IS_SET(ch->fighting->act2,ACT_MONK))
&& number_percent () < (get_skill (ch->fighting, gsn_prevent_escape)* .60))
{
prevent_escape (ch->fighting, ch);
return;
}
ch->hit -= 60 - ch->perm_stat[STAT_CON];
if (chance > number_percent() && !IS_SET (ch->in_room->room_flags, ROOM_NO_RECALL)
&& !IS_SET (ch->in_room->race_flags, ROOM_NOTRANSPORT) && ch->in_room)
{
WAIT_STATE (ch, skill_table[gsn_escape].beats);
send_to_char("Using your eight legs, you run away from battle faster than anyone ever has before.\n\r",ch);
act("$n scuttles away on his spider legs, giggling and bumping into people.",ch,NULL,NULL,TO_ROOM);
pRoomIndex = get_random_room (ch);
while (IS_SET (pRoomIndex->room_flags, ROOM_ARENA)
|| IS_SET (pRoomIndex->room_flags, ROOM_SILENT)
|| IS_SET (pRoomIndex->room_flags, ROOM_NOMAGIC)
|| pRoomIndex->area->construct
|| pRoomIndex->sector_type == SECT_WATER_OCEAN
|| IS_SET (pRoomIndex->race_flags, ROOM_NOTRANSPORT)
|| IS_SET (pRoomIndex->race_flags, ROOM_NOTELEPORT)
|| (IS_SET(pRoomIndex->area->area_flags,AREA_IMP_ONLY) && get_trust(ch) < MAX_LEVEL)
|| (pRoomIndex->vnum >= ROOM_VNUM_PLAYER_START && pRoomIndex->vnum <= ROOM_VNUM_PLAYER_END)
|| (pRoomIndex->area != ch->in_room->area)
|| !can_move_char(ch,pRoomIndex,FALSE,FALSE)
)
{
pRoomIndex = get_random_room (ch);
if (++counter > 10000)
{
send_to_char("You try to escape through the ground, but alas, it is not bending to your will.\n\r",ch);
act("$n spins around in circles a few times then dives furiously at the ground, rising with a strange look on $s face.",ch,NULL,NULL,TO_ROOM);
return;
}
}
stop_fighting (ch, TRUE);
// Shinowlan 8/30/98 -- Check person fled from to see if we
// need to clear their pending output. This was put in
// to deal with kai, flee, reenter abuse.
if (ch->fighting)
{
if (!IS_NPC (ch->fighting) && (ch->fighting->wait > 0))
{
ch->fighting->desc->inbuf[0] = '\0'; //clear queued input
}
}
char_from_room(ch);
char_to_room(ch,pRoomIndex);
}
else
{
send_to_char("You try to escape through the ground, but alas, it is not bending to your will.\n\r",ch);
act("$n spins around in circles a few times then dives furiously at the ground, rising with a strange look on $s face.",ch,NULL,NULL,TO_ROOM);
WAIT_STATE (ch, skill_table[gsn_escape].beats);
}
}
void death_spasms(CHAR_DATA *ch)
{
AFFECT_DATA af;
af.where = TO_AFFECTS;
af.type = gsn_death_spasms;
af.level = ch->level;
af.duration = 1;
af.modifier = -20;
af.location = APPLY_AC;
if (!IS_SET(ch->affected_by,AFF_HASTE))
af.bitvector = AFF_HASTE;
else af.bitvector = 0;
af.permaff = FALSE;
af.composition = FALSE;
af.comp_name = str_dup ("");
affect_to_char (ch, &af);
af.bitvector = 0;
af.location = APPLY_DAMROLL;
af.modifier = get_skill(ch,gsn_death_spasms)/10.0;
affect_to_char (ch, &af);
af.location = APPLY_HITROLL;
affect_to_char (ch, &af);
send_to_char ("You feel a rush of strength as sweet death draws closer.\n\r", ch);
act ("$n fights back with renewed energy!",ch,NULL,NULL,TO_ROOM);
}
void do_flick (CHAR_DATA * ch, char *argument)
{
CHAR_DATA *victim = NULL;
char flicking_card[MAX_INPUT_LENGTH];
OBJ_DATA *obj, *tobj;
short chance, hands = 0;
chance = get_skill (ch, gsn_flick);
if (chance <= 0)
{
send_to_char ("You flick everyone off.\n\r", ch);
return;
}
argument = one_argument (argument, flicking_card);
if (flicking_card[0] == '\0')
{
send_to_char ("Flock what card at whom?\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, flicking_card)) == NULL)
{
send_to_char ("You don't seem to be carrying that card.\n\r", ch);
return;
}
if (is_affected (ch, gsn_fear))
{
send_to_char ("You are way too scared to consider attacking anyone.\n\r", ch);
return;
}
if (IS_AFFECTED (ch, AFF_CALM) || is_affected (ch, skill_lookup
("Quiet Mountain Lake")))
{
send_to_char ("You are feeling too peaceful to do that now.\n\r", ch);
return;
}
if (obj->item_type != ITEM_CARD)
{
act ("$p is not a card.", ch, obj, NULL, TO_CHAR);
return;
}
for (tobj = ch->carrying; tobj; tobj = tobj->next_content)
{
if ((tobj->wear_loc == WEAR_WIELD_R)
|| (tobj->wear_loc == WEAR_WIELD_L) || (tobj->wear_loc ==
WEAR_HOLD)
|| (tobj->wear_loc == WEAR_SHIELD))
{
if ((tobj->item_type == ITEM_WEAPON
&& (IS_WEAPON_STAT (tobj, WEAPON_TWO_HANDS) && ch->size < SIZE_LARGE))
|| (tobj->item_type == ITEM_INSTRUMENT
&& IS_SET (tobj->value[0], A)))
hands += 2;
else
hands++;
}
}
if (hands > 1)
{
act ("You have no free hand with which to flick $p.", ch, obj,
NULL, TO_CHAR);
return;
}
if (IS_SET (ch->in_room->room_flags, ROOM_SAFE))
{
send_to_char ("You cannot flick a card in a safe room.\n\r", ch);
return;
}
if (argument[0] == '\0')
{
if (ch->fighting != NULL)
victim = ch->fighting;
else
{
send_to_char ("Flick what at whom?\n\r", ch);
return;
}
}
else victim = get_char_room (ch, argument);
if (victim == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
if (victim->in_room)
{
CHAR_DATA *tmp_vict = get_gravity_char_room(victim->in_room);
if (tmp_vict)
victim = tmp_vict;
}
if (victim == ch || is_affected(ch,gsn_gravity))
{
send_to_char ("You can't flick a card at yourself.\n\r", ch);
return;
}
if (is_safe (ch, victim))
return;
WAIT_STATE (ch, skill_table[gsn_flick].beats);
act ("With a snap of $s wrist, $n flicks a card at you.", ch, obj, victim, TO_VICT);
act ("With a snap of $s wrist, $n flicks a card at $N.", ch, obj, victim, TO_NOTVICT);
act ("You flick $p at $N.", ch, obj, victim, TO_CHAR);
flick_card(ch,victim,obj,gsn_flick);
}
void flick_card(CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj, int sn)
{
int chance;
chance = get_skill (ch, gsn_flick);
obj_from_char (obj);
if (!IS_NPC(ch))
save_char_obj (ch);
if (victim->in_room->sector_type == SECT_UNDERWATER)
{
act ("$p floats into the murky depths of the water.", ch, obj,
NULL, TO_CHAR);
obj_to_room (obj, victim->in_room);
act ("$p floats gently into the water.", victim, obj, NULL, TO_ROOM);
return;
}
if (ch->in_room->sector_type == SECT_UNDERWATER)
{
act ("$p floats into the murky depths of the water.", ch, obj,
NULL, TO_CHAR);
obj_to_room (obj, ch->in_room);
act ("$p floats gently into the water.", ch, obj, NULL, TO_ROOM);
return;
}
if (is_affected (victim, gsn_mirror))
{
obj_to_room (obj, victim->in_room);
act
("$p bounces off of your invisible mirror and clatters to the ground.",
victim, obj, NULL, TO_CHAR);
act
("$p bounces off of an invisible mirror and clatters to the ground.",
victim, obj, victim, TO_NOTVICT);
return;
}
chance += get_curr_stat (ch, STAT_DEX) / 3;
chance -= get_curr_stat (victim, STAT_DEX) / 5;
chance += victim->size;
//chance += GET_AC (victim, AC_PIERCE) / 4;
if (IS_NPC (victim))
chance += GET_AC (victim, AC_PIERCE) / 5;
else
chance += GET_AC (victim, AC_PIERCE) / 6;
if (IS_SET (ch->off_flags, OFF_FAST) || IS_AFFECTED (ch, AFF_HASTE))
chance += 5;
if (IS_SET (victim->off_flags, OFF_FAST) || IS_AFFECTED (victim, AFF_HASTE))
chance -= 20;
// chance += (ch->level - victim->level);
if (number_percent () < chance)
{
if (!IS_AWAKE (victim))
victim->position = POS_RESTING;
if (victim && !IS_NPC(victim))
save_char_obj (victim);
if (sn == gsn_flick && number_percent() >= 50)
obj_to_char(obj,victim);
one_hit_throw (ch, victim, sn, obj);
if (ch->fighting == NULL)
{
if (ch->mount != NULL && ch->mount->riders != NULL)
ch->position = POS_MOUNTED;
else
ch->position = POS_STANDING;
}
if (victim->fighting == NULL)
{
if (victim->mount != NULL && victim->mount->riders != NULL)
victim->position = POS_MOUNTED;
else
victim->position = POS_STANDING;
}
}
else
{
act("Your flick missed $N.",ch,NULL,victim,TO_CHAR);
act("$n's flick misses $N.",ch,NULL,victim,TO_NOTVICT);
act("$n's flick misses you.",ch,NULL,victim,TO_VICT);
obj_to_room(obj,ch->in_room);
if ((get_curr_stat (ch, STAT_DEX) < 21
|| get_curr_stat (ch, STAT_CHA) < 14) && number_percent () <= 25)
{
damage (ch, victim, 0, gsn_flick, DAM_NONE, FALSE);
}
// update_aggressor (ch, victim);
}
}
void do_shuffle(CHAR_DATA *ch, char* argument)
{
OBJ_DATA *obj, *obj_next, *tobj;
CHAR_DATA *rch;
int counter=0,max,total=0,counter2=0,hands=0,chance;
if ((chance = get_skill(ch,gsn_shuffle)) < 1)
{
if (ch->sex == SEX_MALE)
{
send_to_char("You reach down and shuffle your twig and berries around. It feels kind of good!\n\r",ch);
act("$n reaches down and shuffles $s twig and berries around. A smile appears on $s face.",ch,NULL,NULL,TO_ROOM);
return;
}
//Damn women, I can't think of an interesting message for them
send_to_char("You reach up and shuffle your hair around, trying to look available to any onlookers.\n\r",ch);
act("$n reaches up and shuffles $s hair around, trying to look available to any onlookers.",ch,NULL,NULL,TO_ROOM);
return;
}
if (ch->move < 200-(ch->perm_stat[STAT_DEX]*2))
{
send_to_char("You're too tired to shuffle your cards right now.\n\r",ch);
return;
}
if (is_affected (ch, gsn_fear))
{
send_to_char ("You are way too scared to consider attacking anyone.\n\r", ch);
return;
}
if (IS_AFFECTED (ch, AFF_CALM) || is_affected (ch, skill_lookup
("Quiet Mountain Lake")))
{
send_to_char ("You are feeling too peaceful to do that now.\n\r", ch);
return;
}
for (tobj = ch->carrying; tobj; tobj = tobj->next_content)
{
if ((tobj->wear_loc == WEAR_WIELD_R)
|| (tobj->wear_loc == WEAR_WIELD_L) || (tobj->wear_loc ==
WEAR_HOLD)
|| (tobj->wear_loc == WEAR_SHIELD))
{
if ((tobj->item_type == ITEM_WEAPON
&& (IS_WEAPON_STAT (tobj, WEAPON_TWO_HANDS) && ch->size < SIZE_LARGE))
|| (tobj->item_type == ITEM_INSTRUMENT
&& IS_SET (tobj->value[0], A)))
hands += 2;
else
hands++;
}
}
if (hands > 1)
{
act ("You have no free hand with which to shuffle.", ch,NULL,NULL, TO_CHAR);
return;
}
max = number_range(5,10);
max *= (chance/100.0);
if (max < 1)
{
send_to_char("Alas, your skill at shuffling is so poor you actually shuffle your deck without spilling any cards.\n\r",ch);
return;
}
WAIT_STATE (ch, skill_table[gsn_shuffle].beats);
send_to_char("You try to shuffle your deck but fail! Cards fly in every direction!\n\r",ch);
act("`bFace contorted in concentration, $n tries to shuffle $n deck but ends up sending cards flying in every direction!``",ch,NULL,NULL,TO_ROOM);
for (obj = ch->carrying;obj != NULL && counter <= max;obj = obj_next)
{
obj_next = obj->next_content;
if (obj->item_type != ITEM_CARD)
continue;
total = 0;
for (rch = ch->in_room->people;rch != NULL;rch = rch->next_in_room)
{
if (rch == ch)
continue;
if (is_safe_spell(ch,rch,FALSE))
continue;
if (is_same_group(ch,rch))
continue;
++total;
}
total = number_range(1,total);
counter2 = 0;
for (rch = ch->in_room->people;rch != NULL;rch = rch->next_in_room)
{
if (rch == ch)
continue;
if (is_safe_spell(ch,rch,FALSE))
continue;
if (is_same_group(ch,rch))
continue;
if (++counter2 == total)
{
flick_card(ch,rch,obj,gsn_shuffle);
++counter;
break;
}
}
}
}
void do_luckythrow (CHAR_DATA * ch, char *argument)
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
int chance;
one_argument (argument, arg);
if ((chance = get_skill (ch, gsn_lucky_throw)) == 0)
{
send_to_char ("You throw your arms into the air. That wasn't very lucky.\n\r", ch);
return;
}
victim = ch->fighting;
if (victim == NULL)
{
send_to_char ("But you aren't in combat!\n\r",ch);
return;
}
if (ch->mana < 80-ch->perm_stat[STAT_DEX])
{
send_to_char ("You throw your arms up in despair. You don't have enough strength to be lucky.\n\r",ch);
return;
}
ch->mana -= 80-ch->perm_stat[STAT_DEX];
if ((get_eq_char(ch,WEAR_WIELD_R) != NULL && !(get_eq_char(ch,WEAR_WIELD_R)->value[0] == WEAPON_DICE))
|| (get_eq_char(ch,WEAR_WIELD_L) != NULL && !(get_eq_char(ch,WEAR_WIELD_L)->value[0] == WEAPON_DICE)))
{
send_to_char("You must be wielding dice for this to work.\n\r",ch);
return;
}
WAIT_STATE(ch,skill_table[gsn_lucky_throw].beats);
if (chance > number_percent())
{
one_hit(ch,victim,-1);
one_hit(ch,victim,-1);
one_hit(ch,victim,-1);
}
else send_to_char("Your luck SUCKS!\n\r",ch);
}
void do_friend(CHAR_DATA *ch, char* argument)
{
CHAR_DATA* mob;
char buf[MAX_STRING_LENGTH];
if (IS_NPC(ch))
return;
if (ch->class != PC_CLASS_CHAOS_JESTER)
{
send_to_char("You attempt to will a friend into existence, but you can't seem to do it.\n\r",ch);
return;
}
if (ch->in_room->area->nplayer > 1)
{
send_to_char("Does your imaginary friend even really exist? Others do not seem to think so.\n\r",ch);
return;
}
if (ch->pcdata->familiar)
{
familiar_poof(ch);
return;
}
mob = create_mobile(get_mob_index(MOB_VNUM_IMAGINARY_FRIEND));
mob->perm_stat[STAT_STR] = ch->perm_stat[STAT_STR]-3;
mob->perm_stat[STAT_INT] = ch->perm_stat[STAT_INT]-3;
mob->perm_stat[STAT_WIS] = ch->perm_stat[STAT_WIS]-3;
mob->perm_stat[STAT_DEX] = ch->perm_stat[STAT_DEX]-3;
mob->perm_stat[STAT_CON] = ch->perm_stat[STAT_CON]-3;
mob->perm_stat[STAT_CHA] = ch->perm_stat[STAT_CHA]-3;
mob->mod_stat[STAT_STR] = 0;
mob->mod_stat[STAT_INT] = 0;
mob->mod_stat[STAT_WIS] = 0;
mob->mod_stat[STAT_DEX] = 0;
mob->mod_stat[STAT_CON] = 0;
mob->mod_stat[STAT_CHA] = 0;
act("Your imaginary friend appears, honks your nose, and then giggles a little.",ch,NULL,NULL,TO_ALL);
sprintf (buf, "%s %s", mob->name, ch->pcdata->familiar_name);
free_string (mob->name);
mob->name = str_dup (buf);
if (str_cmp(ch->pcdata->familiar_name,""))
sprintf (buf, "Your friend %s", ch->pcdata->familiar_name);
else sprintf (buf, "Your friend");
free_string (mob->short_descr);
mob->short_descr = str_dup(buf);
mob->exp = ch->pcdata->familiar_exp;
mob->max_hit = ch->pcdata->familiar_max_hit;
mob->hit = ch->pcdata->familiar_max_hit/2;
mob->max_mana = ch->pcdata->familiar_max_mana;
mob->mana = ch->pcdata->familiar_max_mana;
mob->max_move = ch->pcdata->familiar_max_move;
mob->move = ch->pcdata->familiar_max_move;
mob->level = ch->pcdata->familiar_level;
// sprintf (buf, "%s %s", mob->name, ch->pcdata->familiar_name);
// free_string (mob->name);
// mob->name = str_dup (buf);
mob->afkmsg = str_dup (ch->name);
SET_BIT(mob->act2,ACT_FAMILIAR);
SET_BIT(mob->affected_by,AFF_CHARM);
if (mob->level >= 90)
mob->number_of_attacks = 3;
else if (mob->level >= 45)
mob->number_of_attacks = 2;
else mob->number_of_attacks = 1;
mob->hitroll = mob->level/10 * 10;
mob->damroll = mob->level/10 * 7;
char_to_room(mob,ch->in_room);
add_follower (mob, ch);
ch->pcdata->familiar = mob;
mob->leader = ch;
}
void familiar_poof(CHAR_DATA *ch)
{
OBJ_DATA *obj,*obj_next;
if (!ch->pcdata->familiar)
{
log_string("Familiar poof called on with no familiar -> ");
log_string(ch->name);
return;
}
if (!ch->pcdata->familiar->in_room)
{
log_string("Familiar poof called on familiar not in room for -> ");
log_string(ch->name);
return;
}
for (obj = ch->pcdata->familiar->carrying; obj; obj = obj_next)
{
obj_next = obj->next_content;
unequip_char (ch->pcdata->familiar, obj);
obj_from_char (obj);
obj_to_room (obj,ch->pcdata->familiar->in_room);
act ("$p falls to the ground", ch->pcdata->familiar, obj, NULL, TO_ALL);
}
extract_char(ch->pcdata->familiar,TRUE);
ch->pcdata->familiar = NULL;
}
void do_box(CHAR_DATA *ch, char *argument)
{
OBJ_DATA *box=NULL, *obj=NULL;
char arg[MAX_STRING_LENGTH];
if (ch->class != PC_CLASS_CHAOS_JESTER || IS_NPC(ch))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (argument[0] == '\0')
{
send_to_char("Syntax: box look\n\r get/put OBJ\n\r",ch);
return;
}
argument = one_argument(argument,arg);
box = get_obj_vnum_room(get_room_index(ROOM_VNUM_SWITCHED_LIMBO),OBJ_VNUM_CJ_SHARED_BOX);
if (box == NULL)
{
send_to_char("No box for you!\n\r",ch);
return;
}
if (!str_cmp(arg,"get"))
{
obj = get_obj_list (ch, argument, box->contains);
if (obj == NULL)
{
act ("You see nothing like that in the $p.", ch, box, NULL,
TO_CHAR);
return;
}
get_obj (ch, obj, box);
trap_check(ch,"object",NULL,box);
//Iblis - 3/11/04 - Antiduping Code
if (!IS_NPC(ch))
save_char_obj (ch);
return;
}
if (!str_cmp(arg,"put"))
{
if ((obj = get_obj_carry (ch, argument)) == NULL)
{
send_to_char ("You do not have that item.\n\r", ch);
return;
}
if (obj == box)
{
send_to_char ("You can't fold it into itself.\n\r", ch);
return;
}
// Adeon 7/18/03 -- cant put nosave stuff in containers
if (IS_OBJ_STAT (obj, ITEM_NOSAVE))
{
send_to_char ("Strong magic forces prevent you...\n\r", ch);
return;
}
if (!can_drop_obj (ch, obj))
{
send_to_char ("You can't let go of it.\n\r", ch);
return;
}
if (WEIGHT_MULT (obj) != 100 || obj->item_type == ITEM_QUIVER || WEIGHT_MULTP (obj) != 100)
{
send_to_char
("You have a feeling that would be a bad idea.\n\r", ch);
return;
}
if (box->item_type == ITEM_QUIVER)
{
if (obj->item_type != ITEM_WEAPON || obj->value[0] != WEAPON_ARROW)
{
send_to_char ("Quivers can only hold arrows.\n\r", ch);
return;
}
if (box->value[0] <= quiver_holding (box))
{
send_to_char ("That quiver is full.\n\r", ch);
return;
}
}
if (box->item_type != ITEM_CLAN_DONATION
&& box->item_type != ITEM_NEWCLANS_DBOX
&& box->item_type != ITEM_PLAYER_DONATION
&& box->item_type != ITEM_QUIVER)
{
if (get_obj_weight (obj) +
get_true_weight (box) > (box->value[0] *
10) || get_obj_weight (obj)
> (box->value[3] * 10))
{
send_to_char ("It won't fit.\n\r", ch);
return;
}
}
obj_from_char (obj);
obj_to_obj (obj, box);
if (box != NULL && box->item_type == ITEM_PLAYER_DONATION)
save_player_box (box);
//Iblis - 3/11/04 - Antiduping Code
if (!IS_NPC(ch))
save_char_obj (ch);
act ("$n puts $p in $P.", ch, obj, box, TO_ROOM);
act ("You put $p in $P.", ch, obj, box, TO_CHAR);
trip_triggers(ch, OBJ_TRIG_PUT, obj, NULL, OT_SPEC_NONE);
trap_check(ch,"object",NULL,box);
return;
}
if (!str_cmp(arg,"look"))
{
act ("$p holds:", ch, box, NULL, TO_CHAR);
show_list_to_char (box->contains, ch, TRUE, TRUE);
return;
}
do_box(ch,"");
}
void do_friendxp (CHAR_DATA * ch, char *argument)
{
if (IS_NPC(ch) || ch->class != PC_CLASS_CHAOS_JESTER)
{
send_to_char("Huh?\n\r",ch);
return;
}
// we have a mob thing
if (ch->pcdata->all_xp_familiar)
{
send_to_char ("Your familiar will now only get 50% of the xp.\n\r", ch);
ch->pcdata->all_xp_familiar = FALSE;
//REMOVE_BIT (ch->imm_flags, IMM_SUMMON);
}
else
{
send_to_char ("Your familiar will now get 100% of the xp.\n\r", ch);
ch->pcdata->all_xp_familiar = TRUE;
// SET_BIT (ch->imm_flags, IMM_SUMMON);
}
}