/*************************************************************************** * 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. * ***************************************************************************/ /*$Id: act_obj2.c,v 1.25 2005/04/11 03:24:38 tyrion Exp $*/ #if defined( macintosh ) #include <types.h> #else #include <sys/types.h> #endif #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" extern char* target_name; int skill_depoison_weapon( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; if ( target_name[0] == '\0' ) { send_to_char(AT_DGREEN, "What are you trying to poison?\n\r", ch ); return SKPELL_BOTCHED; } if ( ch->fighting ) { send_to_char(AT_DGREEN, "While you're fighting? I think not.\n\r", ch ); return SKPELL_BOTCHED; } if ( !( obj = get_obj_carry( ch, target_name ) ) ) { send_to_char(AT_DGREEN, "You do not have that item.\n\r", ch ); return SKPELL_BOTCHED; } if ( !IS_OBJ_STAT( obj, ITEM_POISONED ) ) { send_to_char(AT_DGREEN, "That item is not poisoned.\n\r", ch ); return SKPELL_BOTCHED; } /* Now we have a valid weapon...check to see if we have the powder. */ /* Great, we have the ingredients...but is the thief smart enough? */ if ( !IS_NPC( ch ) && get_curr_wis( ch ) < 19 ) { send_to_char(AT_DGREEN, "You can't quite remember what to do...\n\r", ch ); return SKPELL_BOTCHED; } /* And does the thief have steady enough hands? */ if ( !IS_NPC( ch ) && ( get_curr_dex( ch ) < 20 || ch->pcdata->condition[COND_DRUNK] > 0 ) ) { send_to_char(AT_DGREEN, "Your hands aren't steady enough to properly remove the poison.\n\r", ch ); return SKPELL_BOTCHED; } WAIT_STATE( ch, skill_table[sn].beats ); /* Well, I'm tired of waiting. Are you? */ act(AT_GREEN, "You remove the deadly poison!", ch, NULL, NULL, TO_CHAR ); act(AT_GREEN, "$n removes the deadly poison!", ch, NULL, NULL, TO_ROOM ); act(AT_GREEN, "You strip the poison from $p, which loses its wicked luster!", ch, obj, NULL, TO_CHAR ); act(AT_GREEN, "$n strips the poison from $p, which loses its wicked luster!", ch, obj, NULL, TO_ROOM ); REMOVE_BIT( obj->extra_flags, ITEM_POISONED ); /* WHAT? All of that, just for that one bit? How lame. ;) */ return SKPELL_NO_DAMAGE; } void do_acmorph ( CHAR_DATA *ch, OBJ_DATA *obj, int vnum ) { OBJ_INDEX_DATA *pObjIndex; OBJ_DATA *nObj; int level; level = 0; act( AT_BLUE, "You invoke $p.", ch, obj, NULL, TO_CHAR ); act( AT_BLUE, "$n invokes $p.", ch, obj, NULL, TO_ROOM ); if ( !(pObjIndex = get_obj_index( vnum ) ) ) { act( AT_BLUE, "$p whines and sparks, but nothing happens", ch, obj, NULL, TO_CHAR ); return; } level = pObjIndex->level; nObj = create_object( pObjIndex, level ); if ( CAN_WEAR( nObj, ITEM_TAKE ) ) { obj_to_char( nObj, ch ); } else { obj_to_room( nObj, ch->in_room ); } act(AT_BLUE, "$p's form wavers, then solidifies as $P.", ch, obj, nObj, TO_CHAR ); act(AT_BLUE, "$n's $p wavers in form. then solidifies as $P.", ch, obj, nObj, TO_ROOM ); oprog_invoke_trigger( obj, ch, nObj ); extract_obj( obj ); return; } void do_acoload( CHAR_DATA *ch, OBJ_DATA *obj, int vnum ) { OBJ_INDEX_DATA *pObjIndex; OBJ_DATA *nObj; int level; level = 0; act( AT_BLUE, "You invoke $p.", ch, obj, NULL, TO_CHAR ); act( AT_BLUE, "$n invokes $p.", ch, obj, NULL, TO_ROOM ); if ( !(pObjIndex = get_obj_index( vnum ) ) ) { act( AT_BLUE, "$p whines and sparks, but nothing happens", ch, obj, NULL, TO_CHAR ); return; } level = pObjIndex->level; nObj = create_object( pObjIndex, level ); if ( CAN_WEAR( nObj, ITEM_TAKE ) ) { obj_to_char( nObj, ch ); } else { obj_to_room( nObj, ch->in_room ); } act(AT_BLUE, "$p spawns $P.", ch, obj, nObj, TO_CHAR ); act(AT_BLUE, "$n's $p spawns $P.", ch, obj, nObj, TO_ROOM ); oprog_invoke_trigger( obj, ch, nObj ); return; } void do_acmload( CHAR_DATA *ch, OBJ_DATA *obj, int vnum ) { CHAR_DATA *victim; MOB_INDEX_DATA *pMobIndex; AFFECT_DATA af; act( AT_BLUE, "You invoke $p.", ch, obj, NULL, TO_CHAR ); act( AT_BLUE, "$n invokes $p.", ch, obj, NULL, TO_ROOM ); if ( !( pMobIndex = get_mob_index( vnum ) ) ) { act( AT_BLUE, "$p whines and sparks, but nothing happens", ch, obj, NULL, TO_CHAR ); return; } victim = create_mobile( pMobIndex ); char_to_room( victim, ch->in_room ); act(AT_BLUE, "$p spawns $N.", ch, obj, victim, TO_CHAR ); act(AT_BLUE, "$n's $p spawns $N.", ch, obj, victim, TO_ROOM ); if ( victim->master ) stop_follower( victim ); add_follower( victim, ch ); af.type = skill_lookup( "charm person" ); af.duration = 50; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char( victim, &af ); oprog_invoke_trigger( obj, ch, victim ); return; } void do_actrans( CHAR_DATA *ch, OBJ_DATA *obj, int vnum ) { ROOM_INDEX_DATA *location; act( AT_BLUE, "You invoke $p.", ch, obj, NULL, TO_CHAR ); act( AT_BLUE, "$n invokes $p.", ch, obj, NULL, TO_ROOM ); if ( !( location = get_room_index( vnum ) ) ) { act(AT_BLUE, "$p whines and sparks, but nothing happens.", ch, obj, NULL, TO_CHAR ); return; } if ( room_is_private( location ) ) { send_to_char(AT_BLUE, "That room is private right now.\n\r", ch ); return; } if ( ch->fighting ) { act( AT_BLUE, "$p pulses lightly, but fails to function.", ch, obj, NULL, TO_CHAR ); return; } if ( IS_SET(location->room_flags, ROOM_SAFE) && ch->pkill && (ch->combat_timer>0)) { send_to_char(AT_BLUE, "Your blood runs to hot to go into that room!\n\r", ch); return; } act(AT_BLUE, "Everything begins to spin, when it clears you are elsewhere.", ch, obj, NULL, TO_CHAR ); act(AT_BLUE, "$n invokes $p and vanishes in a swirling red mist.", ch, obj, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, location ); act(AT_BLUE, "$n arrives in a swirling red mist.", ch, obj, NULL, TO_ROOM); do_look( ch, "auto" ); oprog_invoke_trigger( obj, ch, ch ); return; } void do_invoke( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; CHAR_DATA *rch; CHAR_DATA *victim; char arg1 [ MAX_INPUT_LENGTH ]; char arg2 [ MAX_INPUT_LENGTH ]; char spellarg [ MAX_INPUT_LENGTH ]; if ( IS_NPC(ch) ) return; rch = get_char( ch ); argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( !(obj = get_obj_carry( ch, arg1 ) ) && ( !(obj = get_obj_wear( ch, arg1 ) ) ) ) { send_to_char( AT_WHITE, "You can't find it.\n\r", ch ); return; } if ( (ch->level < obj->level) && (ch->multied == ch->class) ) { send_to_char(AT_BLUE, "You have not attained the level of mastery to use this item", ch ); act(AT_BLUE, "$n tries to use $p, but is too inexperienced.", ch, obj, NULL, TO_ROOM ); return; } if ( obj->ac_type <= 0 || obj->ac_type >= 6 ) { act( AT_WHITE, "$p cannot be invoked.", ch, obj, NULL, TO_CHAR ); return; } if ( obj->ac_type == 5 && !obj->ac_spell ) { sprintf( log_buf, "Obj[%d] AcType Spell with no Spellname", obj->pIndexData->vnum ); bug( log_buf, 0 ); act( AT_WHITE, "$p cannot be invoked.", ch, obj, NULL, TO_CHAR ); return; } if ( arg2[0] == '\0' ) victim = rch; else if ( !(victim = get_char_world( ch, arg2 ) ) ) { send_to_char( AT_WHITE, "There is no such person in existance.\n\r", ch ); return; } 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 ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_MAGE ) && ( ch->class == CLASS_MAGE || ch->multied == CLASS_MAGE ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_CLERIC ) && ( ch->class == CLASS_CLERIC || ch->multied == CLASS_CLERIC ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_THIEF ) && ( ch->class == CLASS_THIEF || ch->multied == CLASS_THIEF ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_WARRIOR ) && ( ch->class == CLASS_WARRIOR || ch->multied == CLASS_WARRIOR ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_PSI ) && ( ch->class == CLASS_PSIONICIST || ch->multied == CLASS_PSIONICIST ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_DRUID ) && ( ch->class == CLASS_DRUID || ch->multied == CLASS_DRUID ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_RANGER ) && ( ch->class == CLASS_RANGER || ch->multied == CLASS_RANGER ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_PALADIN ) && ( ch->class == CLASS_PALADIN || ch->multied == CLASS_PALADIN ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_BARD ) && ( ch->class == CLASS_BARD || ch->multied == CLASS_BARD ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_VAMP ) && ( ch->class == CLASS_VAMPIRE || ch->multied == CLASS_VAMPIRE) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_WEREWOLF ) && ( ch->class == CLASS_WEREWOLF || ch->multied == CLASS_WEREWOLF ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_ANTIPAL ) && ( ch->class == CLASS_ANTI_PALADIN || ch->multied == CLASS_ANTI_PALADIN ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_ASSASSIN ) && ( ch->class == CLASS_ASSASSIN || ch->multied == CLASS_ASSASSIN ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_MONK ) && ( ch->class == CLASS_MONK || ch->multied == CLASS_MONK ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_BARBARIAN) && ( ch->class == CLASS_BARBARIAN || ch->multied == CLASS_BARBARIAN ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_ILLUSIONIST) && ( ch->class == CLASS_ILLUSIONIST || ch->multied == CLASS_ILLUSIONIST ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_NECROMANCER ) && ( ch->class == CLASS_NECROMANCER || ch->multied == CLASS_NECROMANCER ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_DEMONOLOGIST ) && ( ch->class == CLASS_DEMONOLOGIST || ch->multied == CLASS_DEMONOLOGIST ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_SHAMAN ) && ( ch->class == CLASS_SHAMAN || ch->multied == CLASS_SHAMAN ) ) || ( IS_OBJ_STAT2( obj, ITEM_ANTI_DARKPRIEST ) && ( ch->class == CLASS_DARKPRIEST || ch->multied == CLASS_DARKPRIEST ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_MAGE ) && ( ch->class != CLASS_MAGE && ch->multied != CLASS_MAGE ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_CLERIC ) && ( ch->class != CLASS_CLERIC && ch->multied != CLASS_CLERIC ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_THIEF ) && ( ch->class != CLASS_THIEF && ch->multied != CLASS_THIEF ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_WARRIOR ) && ( ch->class != CLASS_WARRIOR && ch->multied != CLASS_WARRIOR ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_PSI ) && ( ch->class != CLASS_PSIONICIST && ch->multied != CLASS_PSIONICIST ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_DRUID ) && ( ch->class != CLASS_DRUID && ch->multied != CLASS_DRUID ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_RANGER ) && ( ch->class != CLASS_RANGER && ch->multied != CLASS_RANGER ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_PALADIN ) && ( ch->class != CLASS_PALADIN && ch->multied != CLASS_PALADIN ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_BARD ) && ( ch->class != CLASS_BARD && ch->multied != CLASS_BARD ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_VAMP ) && ( ch->class != CLASS_VAMPIRE && ch->multied != CLASS_VAMPIRE) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_WEREWOLF ) && ( ch->class != CLASS_WEREWOLF && ch->multied != CLASS_WEREWOLF ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_ANTIPAL ) && ( ch->class != CLASS_ANTI_PALADIN && ch->multied != CLASS_ANTI_PALADIN ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_ASSASSIN ) && ( ch->class != CLASS_ASSASSIN && ch->multied != CLASS_ASSASSIN ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_MONK ) && ( ch->class != CLASS_MONK && ch->multied != CLASS_MONK ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_BARBARIAN) && ( ch->class != CLASS_BARBARIAN && ch->multied != CLASS_BARBARIAN ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_ILLUSIONIST) && ( ch->class != CLASS_ILLUSIONIST && ch->multied != CLASS_ILLUSIONIST ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_NECROMANCER ) && ( ch->class != CLASS_NECROMANCER && ch->multied != CLASS_NECROMANCER ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_DEMONOLOGIST ) && ( ch->class != CLASS_DEMONOLOGIST && ch->multied != CLASS_DEMONOLOGIST ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_SHAMAN ) && ( ch->class != CLASS_SHAMAN && ch->multied != CLASS_SHAMAN ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_DARKPRIEST ) && ( ch->class != CLASS_DARKPRIEST && ch->multied != CLASS_DARKPRIEST ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_HUMAN ) && ( ch->race != 0 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_ELF ) && ( ch->race != 1 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_HALFELF ) && ( ch->race != 2 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_ORC ) && ( ch->race != 3 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_DROW ) && ( ch->race != 4 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_DWARF ) && ( ch->race != 5 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_HALFDWARF )&& ( ch->race != 6 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_HOBBIT ) && ( ch->race != 7 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_GIANT ) && ( ch->race != 8 ) ) || ( IS_OBJ_STAT3( obj, ITEM_PRO_OGRE ) && ( ch->race != 9 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_ANGEL ) && ( ch->race != 10 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_MINOTAUR ) && ( ch->race != 11 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_FELINE ) && ( ch->race != 12 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_GARGOYLE ) && ( ch->race != 20 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_CANINE ) && ( ch->race != 14 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_DEMON ) && ( ch->race != 15 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_PIXIE ) && ( ch->race != 16 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_ELDER ) && ( ch->race != 17 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_LIZARDMAN )&& ( ch->race != 18 ) ) || ( IS_OBJ_STAT4( obj, ITEM_PRO_GNOME ) && ( ch->race != 19 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_HUMAN ) && ( ch->race == 0 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_ELF ) && ( ch->race == 1 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_HALFELF ) && ( ch->race == 2 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_ORC ) && ( ch->race == 3 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_DROW ) && ( ch->race == 4 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_DWARF ) && ( ch->race == 5 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_HALFDWARF )&& ( ch->race == 6 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_HOBBIT ) && ( ch->race == 7 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_GIANT ) && ( ch->race == 8 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_OGRE ) && ( ch->race == 9 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_ANGEL ) && ( ch->race == 10 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_MINOTAUR ) && ( ch->race == 11 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_FELINE ) && ( ch->race == 12 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_GARGOYLE ) && ( ch->race == 20 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_CANINE ) && ( ch->race == 14 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_DEMON ) && ( ch->race == 15 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_PIXIE ) && ( ch->race == 16 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_ELDER ) && ( ch->race == 17 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_LIZARDMAN )&& ( ch->race == 18 ) ) || ( IS_OBJ_STAT4( obj, ITEM_ANTI_GNOME ) && ( ch->race == 19 ) ) ) { act(AT_BLUE, "You are zapped by $p and drop it.", ch, obj, NULL, TO_CHAR ); act(AT_BLUE, "$n is zapped by $p and drops it.", ch, obj, NULL, TO_ROOM ); obj_from_char( obj ); obj_to_room( obj, ch->in_room ); return; } else if (IS_OBJ_STAT2( obj, ITEM_LEGEND ) && !IS_LEGEND( ch ) ) { act(AT_BLUE, "You somehow don't feel powerful enough for $p and set it on the ground...", ch, obj, NULL, TO_CHAR); act(AT_BLUE, "$n attempts to wear $p, thinks better of it and sets it on the ground.", ch, obj, NULL, TO_ROOM ); obj_from_char( obj ); obj_to_room( obj, ch->in_room ); return; } } switch ( obj->ac_type ) { default: break; case 1: do_acoload( ch, obj, obj->ac_vnum ); break; case 2: do_acmload( ch, obj, obj->ac_vnum ); break; case 3: do_actrans( ch, obj, obj->ac_vnum ); break; case 4: do_acmorph( ch, obj, obj->ac_vnum ); break; case 5: { spellarg[0] = '\0'; sprintf( spellarg, "'%s' %s", obj->ac_spell, arg2 ); do_acspell( ch, obj, spellarg ); break; } } if ( obj->ac_charge[1] != -1 ) if ( -- obj->ac_charge[0] <= 0 ) { act(AT_WHITE, "Your $p sputters and sparks.", ch, obj, NULL, TO_CHAR ); act(AT_WHITE, "$n's $p sputters and sparks..", ch, obj, NULL, TO_ROOM ); obj->ac_type = 0; obj->ac_spell = " "; obj->ac_vnum = 0; } return; } int skill_voodo ( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; CHAR_DATA *victim; char buf [MAX_STRING_LENGTH]; char *name; if( ch->summon_timer > 0 ) { send_to_char(C_DEFAULT, "You try to get it to work, but nothing happens.\n\r", ch ); return SKPELL_MISSED; } buf[0] = '\0'; if ( !(victim = get_char_world( ch, target_name ) ) ) { send_to_char( AT_RED, "No such person exists.", ch ); return SKPELL_MISSED; } if ( saves_spell( ch->level, victim ) ) { send_to_char( AT_RED, "You failed.\n\r", ch ); return SKPELL_MISSED; } if (IS_NPC(victim)) name = victim->short_descr; else name = victim->name; obj = create_object ( get_obj_index( OBJ_VNUM_DOLL ), 0 ); sprintf( buf, obj->short_descr, name ); free_string( obj->short_descr ); obj->short_descr = str_dup( buf ); free_string( obj->name ); obj->name = str_dup( target_name ); obj->timer = 10; ch->summon_timer = 10; obj_to_char(obj, ch); act(AT_RED, "You call upon the Gods to create $p.", ch, obj, NULL, TO_CHAR ); act(AT_RED, "$n calls upon the Gods to create $p.", ch, obj, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } void do_repair ( CHAR_DATA *ch, char *argument ) { char arg[MAX_STRING_LENGTH]; OBJ_DATA *pObj; int cost; char buf[MAX_STRING_LENGTH]; if (IS_NPC(ch)) return; if ( !IS_SET( ch->in_room->room_flags, ROOM_SMITHY ) ) { send_to_char(AT_WHITE, "You are not within a smithy.\n\r", ch ); return; } one_argument( argument, arg ); if ( !str_cmp( arg, "all" ) ) { char buf[MAX_STRING_LENGTH]; for ( pObj = ch->carrying; pObj; pObj = pObj->next_content ) { if ( pObj->wear_loc == WEAR_NONE ) continue; if ( pObj->durability_cur >= pObj->durability_max ) continue; if ( pObj->durability_max <= 10 ) { sprintf( buf, "Your '%s' can no longer be repaired.\n\r", pObj->short_descr ); send_to_char(AT_WHITE, buf, ch ); continue; } cost = (pObj->durability_max - pObj->durability_cur) * pObj->weight * ( pObj->level / 4 ); switch (pObj->item_type) { case ITEM_WEAPON: break; case ITEM_ARMOR: break; default: bug("Do_repair: Item not weapon or armor.",0); break; } if ( cost <= 0 ) cost = 1; if ( cost > ch->gold ) { sprintf(buf, "$p will cost %d, you lack the funds.", cost ); act(AT_WHITE,buf,ch,pObj,NULL,TO_CHAR); continue; } ch->gold -= cost; pObj->cost = pObj->pIndexData->cost; pObj->durability_max -= 1; pObj->durability_cur = pObj->durability_max; REMOVE_BIT(pObj->extra_flags, ITEM_PATCHED); sprintf(buf, "You are charged %d for repairing $p.", cost ); act(AT_WHITE,buf,ch,pObj,NULL,TO_CHAR); if ( pObj->durability_max <= 10 ) { sprintf( buf, "Your '%s' can no longer be repaired.\n\r", pObj->short_descr ); send_to_char(AT_WHITE, buf, ch ); } } return; } if (!( pObj = get_obj_carry ( ch, arg ) ) ) { send_to_char (AT_WHITE, "You do not see that here.\n\r", ch ); return; } if ( pObj->durability_max <= 10 ) { sprintf( buf, "Your '%s' can not be repaired.\n\r", pObj->short_descr ); send_to_char(AT_WHITE, buf, ch ); return; } if ( pObj->durability_max == pObj->durability_cur ) { send_to_char(AT_WHITE, "That item is not damaged.\n\r", ch ); return; } cost = (pObj->pIndexData->cost - pObj->cost); switch( pObj->item_type ) { case ITEM_WEAPON: cost = cost * pObj->value[1] / pObj->value[2]; break; case ITEM_ARMOR: cost = cost * pObj->level / pObj->value[0]; break; default: bug("Do_repair: Item not weapon or armor.", 0); break; } if ( cost <= 0 ) cost = 1; if ( ch->gold < cost ) { char buf[MAX_STRING_LENGTH]; sprintf(buf, "That item will cost %d, you lack the funds.\n\r", cost ); send_to_char( AT_WHITE, buf, ch ); return; } else { char buf[MAX_STRING_LENGTH]; sprintf( buf, "You are charged %d for repairing %s.\n\r", cost, pObj->short_descr ); ch->gold -= cost; send_to_char ( AT_WHITE, buf, ch ); pObj->cost = pObj->pIndexData->cost; pObj->durability_max -= 1; if ( pObj->durability_max <= 10 ) { sprintf( buf, "Your '%s' can no longer be repaired.\n\r", pObj->short_descr ); send_to_char(AT_WHITE, buf, ch ); } pObj->durability_cur = pObj->durability_max; REMOVE_BIT(pObj->extra_flags, ITEM_PATCHED); return; } return; } void do_account( CHAR_DATA *ch, char *argument ) { char arg[MAX_STRING_LENGTH]; if (IS_NPC( ch ) ) return; else { if ( !IS_SET( ch->in_room->room_flags, ROOM_BANK ) ) { send_to_char(AT_WHITE, "You are not in a bank!\n\r", ch ); return; } if ( ch->pcdata->bankaccount > 0 ) { sprintf( arg, "You have %d coin%s in your account.\n\r", ch->pcdata->bankaccount, ch->pcdata->bankaccount > 1 ? "s" : "" ); send_to_char(AT_WHITE, arg, ch ); return; } else { int len = 0; len = strlen( ch->name ); send_to_char(AT_WHITE, "You have nothing in your account!\n\r", ch ); sprintf( arg, "&wFrom the shocked look on $n'%s face, you can tell that they have nothing in their account.", ch->name[len] == 's' ? "" : "s" ); act(AT_WHITE, arg, ch, NULL, NULL, TO_ROOM ); return; } } return; } void do_separate( CHAR_DATA *ch, char *argument ) { OBJ_DATA *Obj; OBJ_DATA *aObj; OBJ_DATA *bObj; OBJ_INDEX_DATA *pIndex; if ( !( Obj = get_obj_carry( ch, argument ) ) ) { send_to_char( AT_WHITE, "You are not carrying that item.\n\r", ch ); return; } if ( !get_obj_index( Obj->pIndexData->sep_one ) || !get_obj_index( Obj->pIndexData->sep_two ) ) { send_to_char( AT_WHITE, "It cannot be separated.\n\r", ch ); return; } pIndex = get_obj_index( Obj->pIndexData->sep_one ); aObj = create_object( pIndex, pIndex->level ); pIndex = get_obj_index( Obj->pIndexData->sep_two ); bObj = create_object( pIndex, pIndex->level ); sprintf( log_buf, "$n separates $p into %s and %s.\n\r", aObj->name, bObj->name ); act( AT_WHITE, log_buf, ch, Obj, NULL, TO_ROOM ); oprog_separate_trigger( Obj, ch ); obj_from_char( Obj ); extract_obj( Obj ); obj_to_char( aObj, ch ); obj_to_char( bObj, ch ); send_to_char( AT_WHITE, "The object is now separated.\n\r", ch ); } void do_join( CHAR_DATA *ch, char *argument ) { OBJ_DATA *aObj; OBJ_DATA *bObj; OBJ_DATA *Obj; OBJ_INDEX_DATA *pIndex; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( !(aObj = get_obj_carry(ch, arg1)) ) { char buf[MAX_STRING_LENGTH]; sprintf( buf, "You are not carrying any %s.\n\r", arg1 ); send_to_char( AT_WHITE, buf, ch ); return; } if ( !(bObj = get_obj_carry(ch, arg2)) ) { char buf[MAX_STRING_LENGTH]; if (strlen( arg2 ) > 0 ) { sprintf( buf, "You are not carrying any %s.\n\r", arg2 ); send_to_char( AT_WHITE, buf, ch ); return; } else if (strlen( arg2 ) <= 0 ) { send_to_char( AT_WHITE, "What's that?\n\r", ch ); return; } } if ( aObj->pIndexData->join != bObj->pIndexData->join || aObj->pIndexData == bObj->pIndexData || !get_obj_index( aObj->pIndexData->join ) ) { char buf[MAX_STRING_LENGTH]; sprintf( buf, "%s cannot be joined with %s.\n\r", capitalize( aObj->short_descr ), bObj->short_descr ); send_to_char( AT_WHITE, buf, ch ); return; } oprog_join_trigger( aObj, ch, bObj ); pIndex = get_obj_index( aObj->pIndexData->join ); Obj = create_object( pIndex, pIndex->level ); obj_to_char( Obj, ch ); sprintf( log_buf, "$n joins $p to $P to create %s.\n\r", Obj->short_descr ); act( AT_WHITE, log_buf, ch, aObj, bObj, TO_ROOM ); obj_from_char( aObj ); extract_obj( aObj ); obj_from_char( bObj ); extract_obj( bObj ); send_to_char( AT_WHITE, "Objects joined.\n\r", ch ); } /* * -- Altrag */ /* * -- Altrag Dalosein */ void do_patch( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; int ammount; int sn = skill_lookup("patched"); if ( IS_NPC( ch ) ) return; if ( ch->pcdata->learned[sn] <= 0 ) { send_to_char(C_DEFAULT, "You don't know how to patch equipment.\n\r",ch); return; } if ( !( obj = get_obj_carry( ch, argument ) ) ) { send_to_char(C_DEFAULT, "You do not have that item.\n\r",ch); return; } if ( obj->item_type != ITEM_WEAPON && obj->item_type != ITEM_ARMOR ) { send_to_char(C_DEFAULT, "You may only repair weapons and armor.\n\r",ch); return; } if ( IS_SET(obj->extra_flags, ITEM_PATCHED) ) { send_to_char(C_DEFAULT, "You can't do much more for it.\n\r",ch); return; } if ( obj->cost >= obj->pIndexData->cost ) { send_to_char(C_DEFAULT, "It already looks like new.\n\r",ch); return; } ammount = ch->pcdata->learned[sn] / 20; ammount = (ammount * (obj->pIndexData->cost - obj->cost)) / 100; obj->cost += ammount; SET_BIT(obj->extra_flags, ITEM_PATCHED); act(AT_WHITE,"$n repairs his $p a bit.",ch,obj,NULL,TO_ROOM); act(AT_WHITE,"You do your best to repair your $p.",ch,obj,NULL,TO_CHAR); return; } int skill_devour( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; int amnt; if ( target_name[0] == '\0' ) { send_to_char(AT_ORANGE, "Devour what?\n\r", ch ); return SKPELL_MISSED; } if ( !( obj = get_obj_carry( ch, target_name ) ) ) { send_to_char(AT_ORANGE, "You do not have that item.\n\r", ch ); return SKPELL_MISSED; } if ( !IS_IMMORTAL( ch ) ) { if ( !IS_NPC( ch ) && ch->pcdata->condition[COND_FULL] > 40 ) { send_to_char(AT_ORANGE, "You are too full to eat more.\n\r", ch ); return SKPELL_BOTCHED; } } act(AT_ORANGE, "You eat $p.", ch, obj, NULL, TO_CHAR ); act(AT_ORANGE, "$n eats $p.", ch, obj, NULL, TO_ROOM ); switch ( obj->item_type ) { case ITEM_FOOD: if ( !IS_NPC( ch ) ) { int condition; condition = ch->pcdata->condition[COND_FULL]; gain_condition( ch, COND_FULL, obj->value[0] ); if ( ch->pcdata->condition[COND_FULL] > 40 ) send_to_char(AT_ORANGE, "You are full.\n\r", ch ); else if ( condition == 0 && ch->pcdata->condition[COND_FULL] > 0 ) send_to_char(AT_ORANGE, "You are no longer hungry.\n\r", ch ); } if ( obj->value[3] != 0 ) { /* The shit was poisoned! */ AFFECT_DATA af; act(AT_GREEN, "$n chokes and gags.", ch, 0, 0, TO_ROOM ); send_to_char(AT_GREEN, "You choke and gag.\n\r", ch ); af.type = skill_lookup("poison"); af.duration = 2 * obj->value[0]; af.location = APPLY_STR; af.modifier = -2; af.bitvector = AFF_POISON; affect_join( ch, &af ); add_poison( ch, obj->value[0] ); } break; case ITEM_BERRY: amnt = number_range( obj->value[0], obj->value[1] ); ch->hit = UMIN( ch->hit + amnt, ch->max_hit ); update_pos( ch ); send_to_char(AT_ORANGE, "You feel warm all over.\n\r", ch); break; case ITEM_PILL: obj_cast_spell( obj->value[1], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[2], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[3], obj->value[0], ch, ch, NULL ); break; } extract_obj( obj ); return SKPELL_NO_DAMAGE; } /* * Hide objects... by Maniac! */ int find_door(CHAR_DATA *ch, char *arg); void do_hide_obj(CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; int chance; int door; OBJ_DATA *obj; one_argument(argument,arg); if ( arg[0] == '\0' ) { send_to_char(AT_WHITE,"What do you want to hide?\n\r", ch); return; } if ( (door = find_door( ch, arg)) >=0 ) /* re-hide hidden exits --Manaux */ { if ( !IS_SET(ch->in_room->exit[door]->exit_info, EX_HIDDEN) && IS_SET(ch->in_room->exit[door]->rs_flags, EX_HIDDEN) ) { SET_BIT( ch->in_room->exit[door]->exit_info, EX_HIDDEN); send_to_char(AT_WHITE, "You successfully re-hide it.", ch); return; } send_to_char(AT_WHITE, "You can't hide that!", ch); return; } if ( !( obj = get_obj_carry( ch, arg ) ) ) { send_to_char(AT_WHITE, "You do not have that item.\n\r", ch ); return; } if ( !can_drop_obj( ch, obj ) ) { // if ( !IS_SET(obj->extra_flags2, ITEM_QUEST) ) send_to_char(AT_WHITE, "You can't let go of it.\n\r", ch ); /* else send_to_char(AT_WHITE, "Your precious quest equipment?\n\r", ch); */ return; } obj_from_char( obj ); obj_to_room( obj, ch->in_room ); if (IS_SET(obj->extra_flags2, ITEM_HIDDEN)) /* no use in hiding it again */ return; chance = number_range(1, 5); if (ch->class == 6) /* Rangers are better */ chance += 2; if (ch->class == 2) /* Thieves as wel, but not so good */ chance++; if (chance > 5) /* Let's not push it... */ chance = 5; if (ch->level > LEVEL_HERO ) /* Immortals will manage */ chance = 5; switch (chance) /* Let's see what we've got */ { case 1: act(AT_WHITE,"$n is on all fours trying to hide $p.", ch, obj, NULL, TO_ROOM ); act(AT_WHITE,"You try to hide $p, but fail misarably.", ch, obj, NULL, TO_CHAR ); break; case 2: act(AT_WHITE,"$n is on all fours digging in the dirt.", ch, NULL, NULL, TO_ROOM ); act(AT_WHITE,"You hide $p, but you did it quite obvious.", ch, obj, NULL, TO_CHAR ); SET_BIT(obj->extra_flags2, ITEM_HIDDEN); break; case 3: act(AT_WHITE, "You fail to hide $p.", ch, obj, NULL, TO_CHAR ); break; case 4: case 5: act(AT_WHITE, "You hide $p.", ch, obj, NULL, TO_CHAR ); SET_BIT(obj->extra_flags2, ITEM_HIDDEN); break; } } void do_search(CHAR_DATA *ch, char *argument) { OBJ_DATA *obj; char buf[MAX_INPUT_LENGTH]; char buf2[MAX_INPUT_LENGTH]; int found = FALSE; bool foundExit = FALSE; int chance; int door; int percent; int sn = skill_lookup("search"); EXIT_DATA *pexit; buf[0] = '\0'; buf2[0] = '\0'; WAIT_STATE( ch, skill_table[sn].beats ); percent = number_percent( ); if ( !IS_NPC( ch ) && percent < ( ch->pcdata->learned[sn] / 10 ) + 35 ) { if (!IS_NPC(ch) && ch->pcdata->learned[sn]) update_skpell(ch, sn, 0); for ( obj = ch->in_room->contents; obj && (!found); obj = obj->next_content ) { if ( IS_SET(obj->extra_flags2, ITEM_HIDDEN) ) { chance = number_range( 1, 5); if ((ch->class == 6) || (ch->class == 2)) chance++; if (chance > 3) { sprintf(buf, "You find %s.\n\r", obj->short_descr); strcat(buf2, buf); buf[0] = '\0'; REMOVE_BIT(obj->extra_flags2, ITEM_HIDDEN); found = TRUE; } } } /*Make search find hidden exits. */ for ( door = 0; door < 6 ; door++) { if ((pexit = ch->in_room->exit[door]) &&IS_SET(pexit->exit_info, EX_HIDDEN) ) { REMOVE_BIT( pexit->exit_info , EX_HIDDEN ) ; if (!foundExit) { foundExit = TRUE; send_to_char(AT_WHITE, "You revealed a hidden exit.\n\r", ch); } } } } if (!found && !foundExit) strcat(buf2, "You find nothing.\n\t"); send_to_char(AT_WHITE,buf2, ch); buf2[0] = '\0'; } int skill_lore( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; if ( target_name[0] == '\0' ) { send_to_char(AT_WHITE,"What do you want to lore?\n\r", ch); return SKPELL_BOTCHED; } obj = get_obj_carry(ch,target_name); if ( obj == NULL ) { send_to_char(AT_WHITE,"You aren't carrying that.\n\r", ch); return SKPELL_BOTCHED; } WAIT_STATE(ch, skill_table[sn].beats); if ( !IS_NPC(ch) && number_percent( ) > ( ch->pcdata->learned[sn] / 10 ) ) { act(AT_WHITE,"You look at $p, but you can't find out any additional information.", ch,obj,NULL,TO_CHAR); act(AT_WHITE,"$n looks at $p but cannot find out anything.", ch, obj, NULL, TO_ROOM); return SKPELL_MISSED; } else { act(AT_WHITE,"$n studies $p, discovering all of it's hidden powers.",ch,obj,NULL,TO_ROOM); if ( ( number_percent( ) * number_percent( ) ) < 40 ) { obj->cost += (int) ( (ch->pcdata->learned[sn]) * 0.01 * obj->cost); send_to_char(AT_WHITE, "Your understanding of the lore behind it increases its worth!\n\r", ch ); } spell_identify(sn,( 4 * obj->level )/3,ch,obj); /* check_improve(ch,gsn_lore,TRUE,4); */ } return SKPELL_NO_DAMAGE; } int skill_embalm( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = 0; return SKPELL_MISSED; if ( target_name[0] == '\0' ) { send_to_char(AT_WHITE,"What do you want to embalm?\n\r", ch); return SKPELL_BOTCHED; } if ( obj->item_type != ITEM_CORPSE_PC ) { send_to_char(AT_WHITE, "You can't embalm that!\n\r", ch); return SKPELL_BOTCHED; } if (IS_SET(obj->wear_flags, ITEM_TAKE)) return SKPELL_NO_DAMAGE; if ( ( obj->item_type = ITEM_CORPSE_PC ) ) { obj->wear_flags = 1; send_to_char(AT_WHITE, "You have embalmed the player's corpse successfully!", ch); return SKPELL_NO_DAMAGE; } return SKPELL_MISSED; } int skill_gravebind( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; int gain = 0; if ( !IS_NPC( ch ) && ( ( ch->level < skill_table[sn].skill_level[ch->class] ) && (ch->level < skill_table[sn].skill_level[ch->multied]))) { send_to_char(C_DEFAULT, "You'd better leave the arts of the dead to the necromancers.\n\r", ch); return SKPELL_BOTCHED; } if ( target_name[0] == '\0' ) { send_to_char(C_DEFAULT, "Gravebind what?\n\r", ch ); return SKPELL_BOTCHED; } obj = (OBJ_DATA*) vo;//get_obj_list( ch, target_name, ch->in_room->contents ); if ( !obj ) { send_to_char(C_DEFAULT, "You can't find it.\n\r", ch ); return SKPELL_BOTCHED; } if ( obj->item_type != ITEM_CORPSE_NPC ) { send_to_char(C_DEFAULT, "You can only gravebind corpses of non-players.\n\r", ch ); return SKPELL_BOTCHED; } if ( ( obj->item_type = ITEM_CORPSE_NPC ) ) { gain = number_range((int)(ch->max_hit * 0.3), (int)(ch->max_hit * 0.5)) + obj->value[1]; if (ch->max_hit >= (ch->hit + gain)) ch->hit = (ch->hit + gain); else { gain = (ch->max_hit - ch->hit); ch->hit = (ch->hit + gain); } ch->move -= (int)(gain/12); /* Added penalty due to new heal range */ send_to_char(AT_GREY, "You absorb the lasting strength of the corpse.\n\r", ch); act(AT_GREY, "$n drains the corpse of its lasting energy.", ch, NULL, NULL, TO_ROOM); extract_obj( obj ); } return SKPELL_NO_DAMAGE; } int skill_gorge( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA * obj; int amount; if ( IS_NPC( ch ) ) { return SKPELL_BOTCHED; } if ( target_name[ 0 ] == '\0' ) { for (obj = ch->in_room->contents; obj; obj = obj->next_content ) { if ( obj->item_type == ITEM_BLOOD ) break; } if ( !obj ) { send_to_char ( AT_RED, "Gorge from what?\n\r", ch ); return SKPELL_MISSED; } } else { if ( !( obj = get_obj_here ( ch, target_name ) ) ) { send_to_char ( AT_BLUE, "You can't find it.\n\r", ch ); return SKPELL_MISSED; } } if ( obj->item_type != ITEM_BLOOD ) { send_to_char ( AT_RED, "You can't gorge yourself from that.\n\r", ch ); return SKPELL_BOTCHED; } if ( ( ch->bp + 1 ) > ch->max_bp ) { send_to_char ( AT_RED, "Your thirst for blood has been abated.\n\r", ch ); return SKPELL_NO_DAMAGE; } /* amount = UMIN ( (ch->max_bp - ch->bp ), obj->value[1] ); amount = UMIN ( amount, 25 ); */ if( !IS_NPC( ch ) ) { amount = number_fuzzy( ch->pcdata->learned[sn] / 25 ) + number_fuzzy( ch->level / 10 ); } else { amount = number_fuzzy( ch->level / 10 ); } ch->bp += amount; if ( obj->value[0] != -1 ) obj->value[1] -= amount; if ( obj->value[1] > 0 ) { act ( AT_RED, "You gorge yourself from $p.", ch, obj, NULL, TO_CHAR ); act ( AT_RED, "$n gorges $mself from $p.", ch, obj, NULL, TO_ROOM ); } else { act ( AT_RED, "You gorge yourself from $p, which vanishes.", ch, obj, NULL, TO_CHAR ); act ( AT_RED, "$n gorges $mself from $p, which vanishes.", ch, obj, NULL, TO_ROOM ); extract_obj ( obj ); } return SKPELL_NO_DAMAGE; }