#include <math.h> #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> #include <time.h> #include "mud.h" char * const spell_flag[] = { "water", "earth", "air", "astral", "area", "distant", "reverse", "save_half_dam", "save_negates", "accumulative", "recastable", "noscribe", "nobrew", "group", "object", "character", "secretskill", "pksensitive" }; char * const spell_saves[] = { "none", "poison_death", "wands", "para_petri", "breath", "spell_staff" }; char * const spell_damage[] = { "none", "fire", "cold", "electricity", "energy", "acid", "poison", "drain" }; char * const spell_action[] = { "none", "create", "destroy", "resist", "suscept", "divinate", "obscure", "change" }; char * const spell_power[] = { "none", "minor", "greater", "major" }; char * const spell_class[] = { "none", "lunar", "solar", "travel", "summon", "life", "death", "illusion" }; char * const target_type[] = { "ignore", "offensive", "defensive", "self", "objinv"}; void show_char_to_char( CHAR_DATA *list, CHAR_DATA *ch ); void show_list_to_char( OBJ_DATA *list, CHAR_DATA *ch, bool fShort, bool fShowN ); int ris_save( CHAR_DATA *ch, int chance, int ris ); bool check_illegal_psteal( CHAR_DATA *ch, CHAR_DATA *victim ); /* from magic.c */ void failed_casting( struct skill_type *skill, CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj ); int xp_compute args( ( CHAR_DATA *gch, CHAR_DATA *victim ) ); ROOM_INDEX_DATA *generate_exit( ROOM_INDEX_DATA *in_room, EXIT_DATA **pexit ); /* * Dummy function */ void skill_notfound( CHAR_DATA *ch, char *argument ) { send_to_char( "Huh?\n\r", ch ); return; } int get_ssave( char *name ) { int x; for ( x = 0; x < sizeof(spell_saves) / sizeof(spell_saves[0]); x++ ) if ( !str_cmp( name, spell_saves[x] ) ) return x; return -1; } int get_starget( char *name ) { int x; for ( x = 0; x < sizeof(target_type) / sizeof(target_type[0]); x++ ) if ( !str_cmp( name, target_type[x] ) ) return x; return -1; } int get_sflag( char *name ) { int x; for ( x = 0; x < sizeof(spell_flag) / sizeof(spell_flag[0]); x++ ) if ( !str_cmp( name, spell_flag[x] ) ) return x; return -1; } int get_sdamage( char *name ) { int x; for ( x = 0; x < sizeof(spell_damage) / sizeof(spell_damage[0]); x++ ) if ( !str_cmp( name, spell_damage[x] ) ) return x; return -1; } int get_saction( char *name ) { int x; for ( x = 0; x < sizeof(spell_action) / sizeof(spell_action[0]); x++ ) if ( !str_cmp( name, spell_action[x] ) ) return x; return -1; } int get_spower( char *name ) { int x; for ( x = 0; x < sizeof(spell_power) / sizeof(spell_power[0]); x++ ) if ( !str_cmp( name, spell_power[x] ) ) return x; return -1; } int get_sclass( char *name ) { int x; for ( x = 0; x < sizeof(spell_class) / sizeof(spell_class[0]); x++ ) if ( !str_cmp( name, spell_class[x] ) ) return x; return -1; } bool is_legal_kill(CHAR_DATA *ch, CHAR_DATA *vch) { if ( IS_NPC(ch) || IS_NPC(vch) ) return TRUE; if ( is_safe(ch,vch) ) return FALSE; return TRUE; } extern char *target_name; /* from magic.c */ /* * Perform a binary search on a section of the skill table * Each different section of the skill table is sorted alphabetically * Only match skills player knows -Thoric */ bool check_skill( CHAR_DATA *ch, char *command, char *argument ) { int sn; int first = gsn_first_skill; int top = gsn_first_weapon-1; struct timeval time_used; int mana; /* bsearch for the skill */ for (;;) { sn = (first + top) >> 1; if ( LOWER(command[0]) == LOWER(skill_table[sn]->name[0]) && !str_prefix(command, skill_table[sn]->name) && (skill_table[sn]->skill_fun || skill_table[sn]->spell_fun != spell_null) && (IS_NPC(ch) || ( ch->pcdata->learned[sn] > 0 )) ) break; if (first >= top) return FALSE; if (strcmp( command, skill_table[sn]->name) < 1) top = sn - 1; else first = sn + 1; } if ( !check_pos( ch, skill_table[sn]->minimum_position ) ) return TRUE; if ( IS_NPC(ch) && (IS_AFFECTED( ch, AFF_CHARM ) || IS_AFFECTED( ch, AFF_POSSESS )) ) { send_to_char( "For some reason, you seem unable to perform that...\n\r", ch ); act( AT_GREY,"$n looks around.", ch, NULL, NULL, TO_ROOM ); return TRUE; } /* check if mana is required */ if ( skill_table[sn]->min_mana ) { mana = IS_NPC(ch) ? 0 : skill_table[sn]->min_mana; if ( !IS_NPC(ch) && ch->mana < mana ) { send_to_char( "You need to rest before using the Force any more.\n\r", ch ); return TRUE; } } else { mana = 0; } /* * Is this a real do-fun, or a really a spell? */ if ( !skill_table[sn]->skill_fun ) { ch_ret retcode = rNONE; void *vo = NULL; CHAR_DATA *victim = NULL; OBJ_DATA *obj = NULL; target_name = ""; switch ( skill_table[sn]->target ) { default: bug( "Check_skill: bad target for sn %d.", sn ); send_to_char( "Something went wrong...\n\r", ch ); return TRUE; case TAR_IGNORE: vo = NULL; if ( argument[0] == '\0' ) { if ( (victim=who_fighting(ch)) != NULL ) target_name = victim->name; } else target_name = argument; break; case TAR_CHAR_OFFENSIVE: if ( argument[0] == '\0' && (victim=who_fighting(ch)) == NULL ) { ch_printf( ch, "%s who?\n\r", capitalize( skill_table[sn]->name ) ); return TRUE; } else if ( argument[0] != '\0' && (victim=get_char_room(ch, argument)) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return TRUE; } if ( is_safe( ch, victim ) ) return TRUE; vo = (void *) victim; break; case TAR_CHAR_DEFENSIVE: if ( argument[0] != '\0' && (victim=get_char_room(ch, argument)) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return TRUE; } if ( !victim ) victim = ch; vo = (void *) victim; break; case TAR_CHAR_SELF: vo = (void *) ch; break; case TAR_OBJ_INV: if ( (obj=get_obj_carry(ch, argument)) == NULL ) { send_to_char( "You can't find that.\n\r", ch ); return TRUE; } vo = (void *) obj; break; } /* waitstate */ WAIT_STATE( ch, skill_table[sn]->beats ); /* check for failure */ if ( (number_percent( ) + skill_table[sn]->difficulty * 5) > (IS_NPC(ch) ? 75 : ch->pcdata->learned[sn]) ) { failed_casting( skill_table[sn], ch, vo, obj ); learn_from_failure( ch, sn ); if ( mana ) { ch->mana -= mana/2; } return TRUE; } if ( mana ) { ch->mana -= mana; } start_timer(&time_used); retcode = (*skill_table[sn]->spell_fun) ( sn, ch->top_level, ch, vo ); end_timer(&time_used); update_userec(&time_used, &skill_table[sn]->userec); if ( retcode == rCHAR_DIED || retcode == rERROR ) return TRUE; if ( char_died(ch) ) return TRUE; if ( retcode == rSPELL_FAILED ) { learn_from_failure( ch, sn ); retcode = rNONE; } else learn_from_success( ch, sn ); if ( skill_table[sn]->target == TAR_CHAR_OFFENSIVE && victim != ch && !char_died(victim) ) { CHAR_DATA *vch; CHAR_DATA *vch_next; for ( vch = ch->in_room->first_person; vch; vch = vch_next ) { vch_next = vch->next_in_room; if ( victim == vch && !victim->fighting && victim->master != ch ) { retcode = multi_hit( victim, ch, TYPE_UNDEFINED ); break; } } } return TRUE; } if ( mana ) { ch->mana -= mana; } ch->prev_cmd = ch->last_cmd; /* haus, for automapping */ ch->last_cmd = skill_table[sn]->skill_fun; start_timer(&time_used); (*skill_table[sn]->skill_fun) ( ch, argument ); end_timer(&time_used); update_userec(&time_used, &skill_table[sn]->userec); tail_chain( ); return TRUE; } /* * Lookup a skills information * High god command */ void do_slookup( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; int sn; SKILLTYPE *skill = NULL; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Slookup what?\n\r", ch ); return; } if ( !str_cmp( arg, "all" ) ) { for ( sn = 0; sn < top_sn && skill_table[sn] && skill_table[sn]->name; sn++ ) pager_printf( ch, "Sn: %4d Slot: %4d Skill/spell: '%-20s' Damtype: %s\n\r", sn, skill_table[sn]->slot, skill_table[sn]->name, spell_damage[SPELL_DAMAGE( skill_table[sn] )] ); } else if ( !str_cmp( arg, "herbs" ) ) { for ( sn = 0; sn < top_herb && herb_table[sn] && herb_table[sn]->name; sn++ ) pager_printf( ch, "%d) %s\n\r", sn, herb_table[sn]->name ); } else { SMAUG_AFF *aff; int cnt = 0; if ( arg[0] == 'h' && is_number(arg+1) ) { sn = atoi(arg+1); if ( !IS_VALID_HERB(sn) ) { send_to_char( "Invalid herb.\n\r", ch ); return; } skill = herb_table[sn]; } else if ( is_number(arg) ) { sn = atoi(arg); if ( (skill=get_skilltype(sn)) == NULL ) { send_to_char( "Invalid sn.\n\r", ch ); return; } sn %= 1000; } else if ( ( sn = skill_lookup( arg ) ) >= 0 ) skill = skill_table[sn]; else if ( ( sn = herb_lookup( arg ) ) >= 0 ) skill = herb_table[sn]; else { send_to_char( "No such skill, spell, proficiency or tongue.\n\r", ch ); return; } if ( !skill ) { send_to_char( "Not created yet.\n\r", ch ); return; } ch_printf( ch, "Sn: %4d Slot: %4d %s: '%-20s'\n\r", sn, skill->slot, skill_tname[skill->type], skill->name ); if ( skill->flags ) { int x; ch_printf( ch, "Damtype: %s Acttype: %s Classtype: %s Powertype: %s\n\r", spell_damage[SPELL_DAMAGE( skill )], spell_action[SPELL_ACTION( skill )], spell_class[SPELL_CLASS( skill )], spell_power[SPELL_POWER( skill )] ); strcpy( buf, "Flags:" ); for ( x = 11; x < 32; x++ ) if ( SPELL_FLAG( skill, 1 << x ) ) { strcat( buf, " " ); strcat( buf, spell_flag[x-11] ); } strcat( buf, "\n\r" ); send_to_char( buf, ch ); } ch_printf( ch, "Saves: %s\n\r", spell_saves[(int) skill->saves] ); if ( skill->difficulty != '\0' ) ch_printf( ch, "Difficulty: %d\n\r", (int) skill->difficulty ); ch_printf( ch, "Type: %s Target: %s Minpos: %d Mana: %d Beats: %d\n\r", skill_tname[skill->type], target_type[URANGE(TAR_IGNORE, skill->target, TAR_OBJ_INV)], skill->minimum_position, skill->min_mana, skill->beats ); ch_printf( ch, "Flags: %d Guild: %d Code: %s\n\r", skill->flags, skill->guild, skill->skill_fun ? skill_name(skill->skill_fun) : spell_name(skill->spell_fun)); ch_printf( ch, "Dammsg: %s\n\rWearoff: %s\n", skill->noun_damage, skill->msg_off ? skill->msg_off : "(none set)" ); if ( skill->dice && skill->dice[0] != '\0' ) ch_printf( ch, "Dice: %s\n\r", skill->dice ); if ( skill->teachers && skill->teachers[0] != '\0' ) ch_printf( ch, "Teachers: %s\n\r", skill->teachers ); if ( skill->components && skill->components[0] != '\0' ) ch_printf( ch, "Components: %s\n\r", skill->components ); if ( skill->participants ) ch_printf( ch, "Participants: %d\n\r", (int) skill->participants ); if ( skill->userec.num_uses ) send_timer(&skill->userec, ch); for ( aff = skill->affects; aff; aff = aff->next ) { if ( aff == skill->affects ) send_to_char( "\n\r", ch ); sprintf( buf, "Affect %d", ++cnt ); if ( aff->location ) { strcat( buf, " modifies " ); strcat( buf, a_types[aff->location % REVERSE_APPLY] ); strcat( buf, " by '" ); strcat( buf, aff->modifier ); if ( aff->bitvector ) strcat( buf, "' and" ); else strcat( buf, "'" ); } if ( aff->bitvector ) { int x; strcat( buf, " applies" ); for ( x = 0; x < 32; x++ ) if ( IS_SET(aff->bitvector, 1 << x) ) { strcat( buf, " " ); strcat( buf, a_flags[x] ); } } if ( aff->duration[0] != '\0' && aff->duration[0] != '0' ) { strcat( buf, " for '" ); strcat( buf, aff->duration ); strcat( buf, "' rounds" ); } if ( aff->location >= REVERSE_APPLY ) strcat( buf, " (affects caster only)" ); strcat( buf, "\n\r" ); send_to_char( buf, ch ); if ( !aff->next ) send_to_char( "\n\r", ch ); } if ( skill->hit_char && skill->hit_char[0] != '\0' ) ch_printf( ch, "Hitchar : %s\n\r", skill->hit_char ); if ( skill->hit_vict && skill->hit_vict[0] != '\0' ) ch_printf( ch, "Hitvict : %s\n\r", skill->hit_vict ); if ( skill->hit_room && skill->hit_room[0] != '\0' ) ch_printf( ch, "Hitroom : %s\n\r", skill->hit_room ); if ( skill->miss_char && skill->miss_char[0] != '\0' ) ch_printf( ch, "Misschar : %s\n\r", skill->miss_char ); if ( skill->miss_vict && skill->miss_vict[0] != '\0' ) ch_printf( ch, "Missvict : %s\n\r", skill->miss_vict ); if ( skill->miss_room && skill->miss_room[0] != '\0' ) ch_printf( ch, "Missroom : %s\n\r", skill->miss_room ); if ( skill->die_char && skill->die_char[0] != '\0' ) ch_printf( ch, "Diechar : %s\n\r", skill->die_char ); if ( skill->die_vict && skill->die_vict[0] != '\0' ) ch_printf( ch, "Dievict : %s\n\r", skill->die_vict ); if ( skill->die_room && skill->die_room[0] != '\0' ) ch_printf( ch, "Dieroom : %s\n\r", skill->die_room ); if ( skill->imm_char && skill->imm_char[0] != '\0' ) ch_printf( ch, "Immchar : %s\n\r", skill->imm_char ); if ( skill->imm_vict && skill->imm_vict[0] != '\0' ) ch_printf( ch, "Immvict : %s\n\r", skill->imm_vict ); if ( skill->imm_room && skill->imm_room[0] != '\0' ) ch_printf( ch, "Immroom : %s\n\r", skill->imm_room ); if ( skill->type != SKILL_HERB && skill->guild >= 0 && skill->guild < MAX_ABILITY) { sprintf(buf, "guild: %s Align: %4d lvl: %3d\n\r", ability_name[skill->guild], skill->alignment, skill->min_level ); send_to_char( buf, ch ); } send_to_char( "\n\r", ch ); } return; } /* * Set a skill's attributes or what skills a player has. * High god command, with support for creating skills/spells/herbs/etc */ void do_sset( CHAR_DATA *ch, char *argument ) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; CHAR_DATA *victim; int value; int sn; bool fAll; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' || arg2[0] == '\0' || (argument[0] == '\0' && strcmp(arg2,"delete"))) { send_to_char( "Syntax: sset <victim> <skill> <value>\n\r", ch ); send_to_char( "or: sset <victim> all <value>\n\r", ch ); if ( get_trust(ch) > LEVEL_SUB_IMPLEM ) { send_to_char( "or: sset save skill table\n\r", ch ); send_to_char( "or: sset save herb table\n\r", ch ); send_to_char( "or: sset create skill 'new skill'\n\r", ch ); send_to_char( "or: sset create herb 'new herb'\n\r", ch ); } if ( get_trust(ch) > LEVEL_GREATER ) { send_to_char( "or: sset <sn> <field> <value>\n\r", ch ); send_to_char( "\n\rField being one of:\n\r", ch ); send_to_char( " name code target minpos slot mana beats dammsg wearoff guild minlevel\n\r", ch ); send_to_char( " type damtype acttype classtype powertype flag dice value difficulty affect\n\r", ch ); send_to_char( " rmaffect level adept hit miss die imm (char/vict/room)\n\r", ch ); send_to_char( " components teachers\n\r", ch ); send_to_char( "Affect having the fields: <location> <modfifier> [duration] [bitvector]\n\r", ch ); send_to_char( "(See AFFECTTYPES for location, and AFFECTED_BY for bitvector)\n\r", ch ); } send_to_char( "Skill being any skill or spell.\n\r", ch ); return; } if ( get_trust(ch) > LEVEL_SUB_IMPLEM && !str_cmp( arg1, "save" ) && !str_cmp( argument, "table" ) ) { if ( !str_cmp( arg2, "skill" ) ) { send_to_char( "Saving skill table...\n\r", ch ); save_skill_table(-1); return; } if ( !str_cmp( arg2, "herb" ) ) { send_to_char( "Saving herb table...\n\r", ch ); save_herb_table(); return; } } if ( get_trust(ch) > LEVEL_SUB_IMPLEM && !str_cmp( arg1, "create" ) && (!str_cmp( arg2, "skill" ) || !str_cmp( arg2, "herb" )) ) { struct skill_type *skill; sh_int type = SKILL_UNKNOWN; if ( !str_cmp( arg2, "herb" ) ) { type = SKILL_HERB; if ( top_herb >= MAX_HERB ) { ch_printf( ch, "The current top herb is %d, which is the maximum. " "To add more herbs,\n\rMAX_HERB will have to be " "raised in mud.h, and the mud recompiled.\n\r", top_sn ); return; } } else if ( top_sn >= MAX_SKILL ) { ch_printf( ch, "The current top sn is %d, which is the maximum. " "To add more skills,\n\rMAX_SKILL will have to be " "raised in mud.h, and the mud recompiled.\n\r", top_sn ); return; } CREATE( skill, struct skill_type, 1 ); if ( type == SKILL_HERB ) { int max, x; herb_table[top_herb++] = skill; for ( max = x = 0; x < top_herb-1; x++ ) if ( herb_table[x] && herb_table[x]->slot > max ) max = herb_table[x]->slot; skill->slot = max+1; } else skill_table[top_sn++] = skill; skill->name = str_dup( argument ); skill->noun_damage = str_dup( "" ); skill->msg_off = str_dup( "" ); skill->spell_fun = spell_smaug; skill->type = type; send_to_char( "Done.\n\r", ch ); return; } if ( arg1[0] == 'h' ) sn = atoi( arg1+1 ); else sn = atoi( arg1 ); if ( get_trust(ch) > LEVEL_GREATER && ((arg1[0] == 'h' && is_number(arg1+1) && (sn=atoi(arg1+1))>=0) || (is_number(arg1) && (sn=atoi(arg1)) >= 0)) ) { struct skill_type *skill; if ( arg1[0] == 'h' ) { if ( sn >= top_herb ) { send_to_char( "Herb number out of range.\n\r", ch ); return; } skill = herb_table[sn]; } else { if ( (skill=get_skilltype(sn)) == NULL ) { send_to_char( "Skill number out of range.\n\r", ch ); return; } sn %= 1000; } if ( !str_cmp( arg2, "difficulty" ) ) { skill->difficulty = atoi( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "participants" ) ) { skill->participants = atoi( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "alignment" ) ) { skill->alignment = atoi( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "damtype" ) ) { int x = get_sdamage( argument ); if ( x == -1 ) send_to_char( "Not a spell damage type.\n\r", ch ); else { SET_SDAM( skill, x ); send_to_char( "Ok.\n\r", ch ); } return; } if ( !str_cmp( arg2, "acttype" ) ) { int x = get_saction( argument ); if ( x == -1 ) send_to_char( "Not a spell action type.\n\r", ch ); else { SET_SACT( skill, x ); send_to_char( "Ok.\n\r", ch ); } return; } if ( !str_cmp( arg2, "classtype" ) ) { int x = get_sclass( argument ); if ( x == -1 ) send_to_char( "Not a spell class type.\n\r", ch ); else { SET_SCLA( skill, x ); send_to_char( "Ok.\n\r", ch ); } return; } if ( !str_cmp( arg2, "powertype" ) ) { int x = get_spower( argument ); if ( x == -1 ) send_to_char( "Not a spell power type.\n\r", ch ); else { SET_SPOW( skill, x ); send_to_char( "Ok.\n\r", ch ); } return; } if ( !str_cmp( arg2, "flag" ) ) { int x = get_sflag( argument ); if ( x == -1 ) send_to_char( "Not a spell flag.\n\r", ch ); else { TOGGLE_BIT( skill->flags, 1 << (x+11) ); send_to_char( "Ok.\n\r", ch ); } return; } if ( !str_cmp( arg2, "saves" ) ) { int x = get_ssave( argument ); if ( x == -1 ) send_to_char( "Not a saving type.\n\r", ch ); else { skill->saves = x; send_to_char( "Ok.\n\r", ch ); } return; } if ( !str_cmp( arg2, "code" ) ) { SPELL_FUN *spellfun; DO_FUN *dofun; if ( (spellfun=spell_function(argument)) != spell_notfound ) { skill->spell_fun = spellfun; skill->skill_fun = NULL; } else if ( (dofun=skill_function(argument)) != skill_notfound ) { skill->skill_fun = dofun; skill->spell_fun = NULL; } else { send_to_char( "Not a spell or skill.\n\r", ch ); return; } send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "target" ) ) { int x = get_starget( argument ); if ( x == -1 ) send_to_char( "Not a valid target type.\n\r", ch ); else { skill->target = x; send_to_char( "Ok.\n\r", ch ); } return; } if ( !str_cmp( arg2, "minpos" ) ) { skill->minimum_position = URANGE( POS_DEAD, atoi( argument ), POS_DRAG ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "minlevel" ) ) { skill->min_level = URANGE( 1, atoi( argument ), MAX_LEVEL ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "slot" ) ) { skill->slot = URANGE( 0, atoi( argument ), 30000 ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "mana" ) ) { skill->min_mana = URANGE( 0, atoi( argument ), 2000 ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "beats" ) ) { skill->beats = URANGE( 0, atoi( argument ), 120 ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "guild" ) ) { skill->guild = atoi( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "value" ) ) { skill->value = atoi( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "type" ) ) { skill->type = get_skill( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "rmaffect" ) ) { SMAUG_AFF *aff = skill->affects; SMAUG_AFF *aff_next; int num = atoi( argument ); int cnt = 1; if ( !aff ) { send_to_char( "This spell has no special affects to remove.\n\r", ch ); return; } if ( num == 1 ) { skill->affects = aff->next; DISPOSE( aff->duration ); DISPOSE( aff->modifier ); DISPOSE( aff ); send_to_char( "Removed.\n\r", ch ); return; } for ( ; aff; aff = aff->next ) { if ( ++cnt == num && (aff_next=aff->next) != NULL ) { aff->next = aff_next->next; DISPOSE( aff_next->duration ); DISPOSE( aff_next->modifier ); DISPOSE( aff_next ); send_to_char( "Removed.\n\r", ch ); return; } } send_to_char( "Not found.\n\r", ch ); return; } /* * affect <location> <modifier> <duration> <bitvector> */ if ( !str_cmp( arg2, "affect" ) ) { char location[MAX_INPUT_LENGTH]; char modifier[MAX_INPUT_LENGTH]; char duration[MAX_INPUT_LENGTH]; char bitvector[MAX_INPUT_LENGTH]; int loc, bit, tmpbit; SMAUG_AFF *aff; argument = one_argument( argument, location ); argument = one_argument( argument, modifier ); argument = one_argument( argument, duration ); if ( location[0] == '!' ) loc = get_atype( location+1 ) + REVERSE_APPLY; else loc = get_atype( location ); if ( (loc % REVERSE_APPLY) < 0 || (loc % REVERSE_APPLY) >= MAX_APPLY_TYPE ) { send_to_char( "Unknown affect location. See AFFECTTYPES.\n\r", ch ); return; } bit = 0; while ( argument[0] != 0 ) { argument = one_argument( argument, bitvector ); if ( (tmpbit=get_aflag( bitvector )) == -1 ) ch_printf( ch, "Unknown bitvector: %s. See AFFECTED_BY\n\r", bitvector ); else bit |= (1 << tmpbit); } CREATE( aff, SMAUG_AFF, 1 ); if ( !str_cmp( duration, "0" ) ) duration[0] = '\0'; if ( !str_cmp( modifier, "0" ) ) modifier[0] = '\0'; aff->duration = str_dup( duration ); aff->location = loc; aff->modifier = str_dup( modifier ); aff->bitvector = bit; aff->next = skill->affects; skill->affects = aff; send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "level" ) ) { skill->min_level = URANGE( 1, atoi( argument ), 100 ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "adept" ) ) { return; } if ( !str_cmp( arg2, "name" ) ) { DISPOSE(skill->name); skill->name = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "dammsg" ) ) { DISPOSE(skill->noun_damage); if ( !str_cmp( argument, "clear" ) ) skill->noun_damage = str_dup( "" ); else skill->noun_damage = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "wearoff" ) ) { DISPOSE(skill->msg_off); if ( str_cmp( argument, "clear" ) ) skill->msg_off = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "hitchar" ) ) { if ( skill->hit_char ) DISPOSE(skill->hit_char); if ( str_cmp( argument, "clear" ) ) skill->hit_char = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "hitvict" ) ) { if ( skill->hit_vict ) DISPOSE(skill->hit_vict); if ( str_cmp( argument, "clear" ) ) skill->hit_vict = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "hitroom" ) ) { if ( skill->hit_room ) DISPOSE(skill->hit_room); if ( str_cmp( argument, "clear" ) ) skill->hit_room = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "misschar" ) ) { if ( skill->miss_char ) DISPOSE(skill->miss_char); if ( str_cmp( argument, "clear" ) ) skill->miss_char = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "missvict" ) ) { if ( skill->miss_vict ) DISPOSE(skill->miss_vict); if ( str_cmp( argument, "clear" ) ) skill->miss_vict = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "missroom" ) ) { if ( skill->miss_room ) DISPOSE(skill->miss_room); if ( str_cmp( argument, "clear" ) ) skill->miss_room = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "diechar" ) ) { if ( skill->die_char ) DISPOSE(skill->die_char); if ( str_cmp( argument, "clear" ) ) skill->die_char = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "dievict" ) ) { if ( skill->die_vict ) DISPOSE(skill->die_vict); if ( str_cmp( argument, "clear" ) ) skill->die_vict = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "dieroom" ) ) { if ( skill->die_room ) DISPOSE(skill->die_room); if ( str_cmp( argument, "clear" ) ) skill->die_room = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "immchar" ) ) { if ( skill->imm_char ) DISPOSE(skill->imm_char); if ( str_cmp( argument, "clear" ) ) skill->imm_char = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "immvict" ) ) { if ( skill->imm_vict ) DISPOSE(skill->imm_vict); if ( str_cmp( argument, "clear" ) ) skill->imm_vict = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "immroom" ) ) { if ( skill->imm_room ) DISPOSE(skill->imm_room); if ( str_cmp( argument, "clear" ) ) skill->imm_room = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "dice" ) ) { if ( skill->dice ) DISPOSE(skill->dice); if ( str_cmp( argument, "clear" ) ) skill->dice = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "components" ) ) { if ( skill->components ) DISPOSE(skill->components); if ( str_cmp( argument, "clear" ) ) skill->components = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_cmp( arg2, "teachers" ) ) { //if ( skill->teachers ) //DISPOSE(skill->teachers); if ( !str_cmp( argument, "clear" ) ) skill->teachers = str_dup( "" ); else { //strcat(skill->teachers, " "); //strcat(skill->teachers, argument); if(skill->teachers) { sprintf(buf, "%s %s", skill->teachers, argument); skill->teachers = str_dup(buf); } else skill->teachers = str_dup(argument); } send_to_char( "Ok.\n\r", ch ); return; } do_sset( ch, "" ); return; } if ( ( victim = get_char_world( ch, arg1 ) ) == NULL ) { if ( (sn = skill_lookup(arg1)) >= 0 ) { sprintf(arg1, "%d %s %s", sn, arg2, argument); do_sset(ch, arg1); } else send_to_char( "They aren't here.\n\r", ch ); return; } if ( IS_NPC(victim) ) { send_to_char( "Not on NPC's.\n\r", ch ); return; } fAll = !str_cmp( arg2, "all" ); sn = 0; if ( !fAll && ( sn = skill_lookup( arg2 ) ) < 0 ) { send_to_char( "No such skill or spell.\n\r", ch ); return; } /* * Snarf the value. */ if ( !is_number( argument ) ) { send_to_char( "Value must be numeric.\n\r", ch ); return; } value = atoi( argument ); if ( value < 0 || value > 100 ) { send_to_char( "Value range is 0 to 100.\n\r", ch ); return; } if ( fAll ) { for ( sn = 0; sn < top_sn; sn++ ) { /* Fix by Narn to prevent ssetting skills the player shouldn't have. */ if (skill_table[sn]->guild < 0 || skill_table[sn]->guild >= MAX_ABILITY ) continue; if ( skill_table[sn]->name && ( victim->skill_level[skill_table[sn]->guild] >= skill_table[sn]->min_level || value == 0 ) ) victim->pcdata->learned[sn] = value; } } else victim->pcdata->learned[sn] = value; return; } void learn_from_success( CHAR_DATA *ch, int sn ) { send_to_char( "Notify the Imms of this.\n\r", ch ); return; } void learn_from_failure( CHAR_DATA *ch, int sn ) { send_to_char( "Notify the Imms of this.\n\r", ch ); return; } void do_detrap( CHAR_DATA *ch, char *argument ) { char arg [MAX_INPUT_LENGTH]; OBJ_DATA *obj; OBJ_DATA *trap; OBJ_DATA *toolkit; int chance; bool has_toolkit = FALSE; bool found = FALSE; switch( ch->substate ) { default: if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( IS_NPC(ch) ) { send_to_char("You do not yet know of this skill.\n\r", ch ); return; } if ( arg[0] == '\0' ) { send_to_char( "Detrap what?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; found = FALSE; if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } if ( !ch->in_room->first_content ) { send_to_char( "You can't find that here.\n\r", ch ); return; } for ( toolkit = ch->last_carrying; obj; obj = obj->prev_content ) { if ( toolkit->item_type == ITEM_TOOLKIT ) { has_toolkit = TRUE; break; } } if( !has_toolkit ) { send_to_char( "You can't do that without a toolkit.\n\r", ch ); return; } for ( obj = ch->in_room->first_content; obj; obj = obj->next_content ) { if ( can_see_obj( ch, obj ) && nifty_is_name( arg, obj->name ) ) { found = TRUE; break; } } if ( !found ) { send_to_char( "You can't find that here.\n\r", ch ); return; } act( AT_ACTION, "You begin your attempt to detrap $p.", ch, obj, NULL, TO_CHAR ); act( AT_ACTION, "$n nervously attempts to disable a trap.", ch, obj, NULL, TO_ROOM ); ch->dest_buf = str_dup( obj->name ); add_timer( ch, TIMER_DO_FUN, number_range(2,8), do_detrap, 1 ); return; case 1: if ( !ch->dest_buf ) { send_to_char( "You were interupted before you could remove the trap!\n\r", ch ); bug( "do_detrap: ch->dest_buf NULL!", 0 ); return; } strcpy( arg, ch->dest_buf ); DISPOSE( ch->dest_buf ); ch->dest_buf = NULL; ch->substate = SUB_NONE; break; case SUB_TIMER_DO_ABORT: DISPOSE(ch->dest_buf); ch->substate = SUB_NONE; send_to_char( "You carefully stop in your attempt to remove the trap.\n\r", ch ); return; } if ( !ch->in_room->first_content ) { send_to_char( "You can't find that here.\n\r", ch ); return; } for ( toolkit = ch->last_carrying; obj; obj = obj->prev_content ) { if( toolkit->item_type == ITEM_TOOLKIT ) { has_toolkit = TRUE; break; } } if( !has_toolkit ) { send_to_char( "You cannot complete your work without a toolkit.\n\r", ch ); return; } for ( obj = ch->in_room->first_content; obj; obj = obj->next_content ) { if ( can_see_obj( ch, obj ) && nifty_is_name( arg, obj->name ) ) { found = TRUE; break; } } if ( !found ) { send_to_char( "You can't find that here.\n\r", ch ); return; } if ( (trap = get_trap( obj )) == NULL ) { send_to_char( "You find no trap on that.\n\r", ch ); return; } chance = skill_roll( ch, DISABLE_DEVICE ); separate_obj(obj); if ( chance < 20 ) { send_to_char( "You made a fatal error and sprung the trap!\n\r", ch ); spring_trap( ch, trap ); return; } extract_obj( trap ); send_to_char( "You have successfully removed the trap.\n\r", ch ); return; } void do_dig( CHAR_DATA *ch, char *argument ) { char arg [MAX_INPUT_LENGTH]; OBJ_DATA *obj; OBJ_DATA *startobj; bool found; bool shovel=FALSE; EXIT_DATA *pexit; int chance; switch( ch->substate ) { default: if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] != '\0' ) { if ( ( pexit = find_door( ch, arg, TRUE ) ) == NULL && get_dir(arg) == -1 ) { send_to_char( "What direction is that?\n\r", ch ); return; } if ( pexit ) { if ( !IS_SET(pexit->exit_info, EX_DIG) && !IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "There is no need to dig out that exit.\n\r", ch ); return; } } } else { switch( ch->in_room->sector_type ) { case SECT_CITY: case SECT_INSIDE: send_to_char( "You will never be able to penetrate the floor.\n\r", ch ); return; case SECT_WATER_SWIM: case SECT_WATER_NOSWIM: case SECT_UNDERWATER: send_to_char( "You cannot dig here.\n\r", ch ); return; case SECT_AIR: send_to_char( "What? In the air?!\n\r", ch ); return; } } for( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if( obj->item_type == ITEM_SHOVEL ) { shovel = TRUE; break; } } if( !shovel ) { send_to_char( "That would be awfully difficult without a shovel.\n\r", ch ); return; } add_timer( ch, TIMER_DO_FUN, 3, do_dig, 1); ch->dest_buf = str_dup( arg ); send_to_char( "You begin digging into the ground.\n\r", ch ); act( AT_PLAIN, "$n begins digging into the ground.", ch, NULL, NULL, TO_ROOM ); return; case 1: if ( !ch->dest_buf ) { send_to_char( "Your digging was interrupted!\n\r", ch ); act( AT_PLAIN, "$n's digging was interrupted!", ch, NULL, NULL, TO_ROOM ); bug( "do_dig: dest_buf NULL", 0 ); return; } strcpy( arg, ch->dest_buf ); DISPOSE( ch->dest_buf ); break; case SUB_TIMER_DO_ABORT: DISPOSE( ch->dest_buf ); ch->substate = SUB_NONE; send_to_char( "You stop digging.\n\r", ch ); act( AT_PLAIN, "$n stops digging.", ch, NULL, NULL, TO_ROOM ); return; } ch->substate = SUB_NONE; for ( obj = ch->first_carrying; obj; obj = obj->next_content ) if ( obj->item_type == ITEM_SHOVEL ) { shovel = TRUE; break; } if( !shovel ) { send_to_char( "You cannot complete your dig without a shovel.\n\r", ch ); return; } chance = skill_roll( ch, SPOT_SKILL ); if ( arg[0] != '\0' ) { if ( ( pexit = find_door( ch, arg, TRUE ) ) != NULL && IS_SET( pexit->exit_info, EX_DIG ) && IS_SET( pexit->exit_info, EX_CLOSED ) ) { if ( chance >= 15 ) { REMOVE_BIT( pexit->exit_info, EX_CLOSED ); send_to_char( "You discover a passageway!\n\r", ch ); act( AT_PLAIN, "$n discovers a passageway!", ch, NULL, NULL, TO_ROOM ); return; } } send_to_char( "Your dig did not discover any passageways.\n\r", ch ); act( AT_PLAIN, "$n's dig did not discover any passageways.", ch, NULL, NULL, TO_ROOM ); return; } startobj = ch->in_room->first_content; found = FALSE; for ( obj = startobj; obj; obj = obj->next_content ) { if ( IS_OBJ_STAT( obj, ITEM_BURRIED ) && chance >= 10 ) { found = TRUE; break; } } if ( !found ) { send_to_char( "You did not discover anything on your dig.\n\r", ch ); act( AT_PLAIN, "$n discovers nothing on $s dig.", ch, NULL, NULL, TO_ROOM ); return; } separate_obj(obj); REMOVE_BIT( obj->extra_flags, ITEM_BURRIED ); act( AT_SKILL, "You find $p in the ground!", ch, obj, NULL, TO_CHAR ); act( AT_SKILL, "$n discovers $p in the ground!", ch, obj, NULL, TO_ROOM ); return; } void do_search( CHAR_DATA *ch, char *argument ) { char arg [MAX_INPUT_LENGTH]; OBJ_DATA *obj; OBJ_DATA *container; OBJ_DATA *startobj; int chance, door; bool found, room; door = -1; switch( ch->substate ) { default: if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( arg[0] != '\0' && (door = get_door( arg )) == -1 ) { container = get_obj_here( ch, arg ); if ( !container ) { send_to_char( "You can't find that here.\n\r", ch ); return; } if ( container->item_type != ITEM_CONTAINER ) { send_to_char( "You can't search in that!\n\r", ch ); return; } if ( IS_SET(container->value[1], CONT_CLOSED) ) { send_to_char( "It is closed.\n\r", ch ); return; } } add_timer( ch, TIMER_DO_FUN, 3, do_search, 1 ); send_to_char( "You begin to search.\n\r", ch ); ch->dest_buf = str_dup( arg ); return; case 1: if ( !ch->dest_buf ) { send_to_char( "Your search was interrupted!\n\r", ch ); bug( "do_search: dest_buf NULL", 0 ); return; } strcpy( arg, ch->dest_buf ); DISPOSE( ch->dest_buf ); break; case SUB_TIMER_DO_ABORT: DISPOSE( ch->dest_buf ); ch->substate = SUB_NONE; send_to_char( "You stop searching.\n\r", ch ); return; } ch->substate = SUB_NONE; if ( arg[0] == '\0' ) { room = TRUE; startobj = ch->in_room->first_content; } else { if ( (door = get_door( arg )) != -1 ) startobj = NULL; else { container = get_obj_here( ch, arg ); if ( !container ) { send_to_char( "You can't find that here.\n\r", ch ); return; } startobj = container->first_content; } } found = FALSE; if ( (!startobj && door == -1) || IS_NPC(ch) ) { send_to_char( "You find nothing.\n\r", ch ); return; } chance = skill_roll( ch, SEARCH_SKILL ); if ( door != -1 ) { EXIT_DATA *pexit; if ( (pexit = get_exit( ch->in_room, door )) != NULL && IS_SET( pexit->exit_info, EX_SECRET ) && IS_SET( pexit->exit_info, EX_xSEARCHABLE ) && chance >= 20 ) { act( AT_SKILL, "After your search, you discover the $d!", ch, NULL, pexit->keyword, TO_CHAR ); act( AT_SKILL, "After searching, $n finds the $d!", ch, NULL, pexit->keyword, TO_ROOM ); REMOVE_BIT( pexit->exit_info, EX_SECRET ); return; } } else for ( obj = startobj; obj; obj = obj->next_content ) { if ( IS_OBJ_STAT( obj, ITEM_HIDDEN ) && chance > 10 ) { found = TRUE; break; } } if ( !found ) { send_to_char( "You find nothing.\n\r", ch ); return; } separate_obj(obj); REMOVE_BIT( obj->extra_flags, ITEM_HIDDEN ); act( AT_SKILL, "After your search, you reveal $p!", ch, obj, NULL, TO_CHAR ); act( AT_SKILL, "$n discovers $p!", ch, obj, NULL, TO_ROOM ); return; } void do_steal( CHAR_DATA *ch, char *argument ) { char logbuf [MAX_STRING_LENGTH]; char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; CHAR_DATA *victim, *rch; OBJ_DATA *obj , *obj_next; int chance, spot, iSpot; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } if ( arg1[0] == '\0' || arg2[0] == '\0' ) { send_to_char( "Steal what from whom?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( victim == ch ) { send_to_char( "That's pointless.\n\r", ch ); return; } if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) ) { set_char_color( AT_MAGIC, ch ); send_to_char( "This isn't a good place to do that.\n\r", ch ); return; } if ( IS_IMMORTAL(victim) ) { send_to_char( "You can't steal from an immortal!\n\r", ch ); return; } WAIT_STATE( ch, PULSE_PER_SECOND*3 ); chance = skill_roll( ch, SLEIGHT_OF_HAND ); spot = skill_roll( victim, SPOT_SKILL ); if ( !IS_AWAKE(victim) || victim->position == POS_FIGHTING ) spot -= number_range(2, 8); if ( chance < 20 ) { if( chance > spot ) { act( AT_ACTION, "You fail to steal from $N, but $E doesn't seem to notice!\n\r", ch, NULL, victim, TO_CHAR ); for( rch = ch->in_room->first_person; rch; rch = rch->next ) { if( rch == ch || rch == victim ) continue; iSpot = 0; iSpot = skill_roll( rch, SPOT_SKILL ); if( iSpot >= chance ) ch_printf( rch, "&BYou see %s fail to steal anything from the oblivious %s", ch->name, victim->name ); } return; } act( AT_ACTION, "You fail to steal from $N and $E has caught you!\n\r", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "You catch $n tring to steal from you!\n\r", ch, NULL, victim, TO_VICT ); for( rch = ch->in_room->first_person; rch; rch = rch->next ) { if( rch == ch || rch == victim ) continue; iSpot = 0; iSpot = skill_roll( rch, SPOT_SKILL ); if( iSpot >= chance ) ch_printf( rch, "&BYou see %s fail to steal anything from the observant %s", ch->name, victim->name ); } if(IS_NPC(victim)) global_retcode = multi_hit( victim, ch, TYPE_UNDEFINED ); return; } for( rch = ch->in_room->first_person; rch; rch = rch->next ) { if( rch == ch || rch == victim ) continue; iSpot = 0; iSpot = skill_roll( rch, SPOT_SKILL ); if( iSpot >= chance ) ch_printf( rch, "&BYou see %s steal from the oblivious %s", ch->name, victim->name ); } if ( !str_cmp( arg1, "credits" ) || !str_cmp( arg1, "credit" ) || !str_cmp( arg1, "money" ) ) { int amount; amount = (int) (victim->gold * number_range(1, 10) / 100); if ( amount <= 0 ) { send_to_char( "You couldn't get any credits.\n\r", ch ); return; } ch->gold += amount; victim->gold -= amount; ch_printf( ch, "&w&WYou managed to steal &G%d&w&W credits!\n\r", amount ); sprintf(logbuf, "%s stole %d credits from %s.\n\r", ch->name, amount, IS_NPC(victim) ? victim->short_descr : victim->name); log_string(logbuf); return; } if ( ( obj = get_obj_carry( victim, arg1 ) ) == NULL ) { if ( victim->position <= POS_SLEEPING ) { if ( ( obj = get_obj_wear( victim, arg1 ) ) != NULL ) { if ( (obj_next=get_eq_char(victim, obj->wear_loc)) != obj ) { ch_printf( ch, "They are wearing %s on top of %s.\n\r", obj_next->short_descr, obj->short_descr); send_to_char( "You'll have to steal that first.\n\r", ch ); return; } else unequip_char( victim, obj ); } } send_to_char( "You can't seem to find it.\n\r", ch ); return; } if ( !can_drop_obj( ch, obj ) || IS_OBJ_STAT(obj, ITEM_INVENTORY) || IS_OBJ_STAT(obj, ITEM_PROTOTYPE)) { send_to_char( "You can't manage to pry it away.\n\r", ch ); return; } if ( ch->carry_number + (get_obj_number(obj)/obj->count) > can_carry_n( ch ) ) { send_to_char( "You have your hands full.\n\r", ch ); return; } if ( ch->carry_weight + (get_obj_weight(obj)/obj->count) > can_carry_w( ch ) ) { send_to_char( "You can't carry that much weight.\n\r", ch ); return; } ch_printf( ch, "&w&WYou stole &G%s&w&W from &G%s&w&W!\n\r", obj->name, victim->name ); sprintf(logbuf, "%s stole %s from %s.\n\r", ch->name, obj->name, IS_NPC(victim) ? victim->short_descr : victim->name ); log_string(logbuf); separate_obj( obj ); obj_from_char( obj ); obj_to_char( obj, ch ); return; } void do_rescue( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; CHAR_DATA *fch; if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } if ( ch->class_level[PROTECTOR_ABILITY] < 2 ) { send_to_char( "Huh?\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Rescue whom?\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( "Rescue yourself, wouldn't that be lovily?\n\r", ch ); return; } if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } if ( !IS_NPC(ch) && IS_NPC(victim) ) { send_to_char( "Doesn't need your help!\n\r", ch ); return; } if ( ( fch = who_fighting( victim) ) == NULL ) { send_to_char( "They are not fighting right now.\n\r", ch ); return; } if ( fch == ch ) { send_to_char("You cannot rescue them from yourself.\n\r", ch); return; } WAIT_STATE( ch, PULSE_VIOLENCE*2 ); act( AT_SKILL, "You succeed in rescueing $N!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n rescues you!", ch, NULL, victim, TO_VICT ); act( AT_SKILL, "$n moves in front of $N!", ch, NULL, victim, TO_NOTVICT ); stop_fighting( fch, FALSE ); stop_fighting( victim, FALSE ); if ( ch->fighting ) stop_fighting( ch, FALSE ); set_fighting( ch, fch ); set_fighting( fch, ch ); return; } void disarm( CHAR_DATA *ch, CHAR_DATA *victim ) { OBJ_DATA *obj, *tmpobj, *ch_wield; int chance, resist; if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL ) return; if ( ( tmpobj = get_eq_char( victim, WEAR_DUAL_WIELD ) ) != NULL ) obj = tmpobj; if ( ( ch_wield = get_eq_char( ch, WEAR_WIELD ) ) != NULL ) if( ch_wield->item_type == ITEM_WEAPON && (ch_wield->value[3] == WEAPON_BLASTER_RIFLE || ch_wield->value[3] == WEAPON_BLASTER || ch_wield->value[3] == WEAPON_BOWCASTER || ch_wield->value[3] == WEAPON_HEAVY ) ) return; if ( IS_NPC( ch ) && !can_see_obj( ch, obj ) ) return; chance = ( number_range(1,20) + ch->hitroll ); resist = ( number_range(1,20) + ch->hitroll ); if ( chance > resist ) { act( AT_SKILL, "$n DISARMS you!", ch, NULL, victim, TO_VICT ); act( AT_SKILL, "You disarm $N!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n disarms $N!", ch, NULL, victim, TO_NOTVICT ); } else { act( AT_SKILL, "$n fails to disarm you!", ch, NULL, victim, TO_VICT ); act( AT_SKILL, "You fail to disarm $N!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n fails to disarm $N!", ch, NULL, victim, TO_NOTVICT ); return; } if ( obj == get_eq_char( victim, WEAR_WIELD ) && (tmpobj = get_eq_char( victim, WEAR_DUAL_WIELD)) != NULL ) tmpobj->wear_loc = WEAR_WIELD; obj_from_char( obj ); if ( ( ch_wield = get_eq_char( ch, WEAR_WIELD ) ) == NULL ) { obj_to_char( obj, ch ); return; } obj_to_room( obj, victim->in_room ); return; } void do_disarm( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; OBJ_DATA *obj; if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } if ( get_eq_char( ch, WEAR_WIELD ) == NULL ) { send_to_char( "You must wield a weapon to disarm.\n\r", ch ); return; } if ( ( victim = who_fighting( ch ) ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL ) { send_to_char( "Your opponent is not wielding a weapon.\n\r", ch ); return; } WAIT_STATE( ch, PULSE_VIOLENCE ); disarm( ch, victim ); return; } void trip( CHAR_DATA *ch, CHAR_DATA *victim ) { OBJ_DATA *armor; int chance, resist, touch, trip; touch = GET_AC(victim); if( ( armor = get_eq_char( victim, WEAR_BODY ) ) != NULL ) touch -= armor->value[0]; chance = ( number_range(1,20) + ch->hitroll ); if( chance < touch ) { act( AT_SKILL, "$n fails to trip you!", ch, NULL, victim, TO_VICT ); act( AT_SKILL, "You fail to trip $N!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n fails to trip $N!", ch, NULL, victim, TO_NOTVICT ); return; } trip = ( number_range( 1, 20 ) + stat_table[get_curr_str(ch)].mod ); resist = number_range(1,20); if( get_curr_str(victim) > get_curr_dex(victim) ) resist += stat_table[get_curr_str(victim)].mod; else resist += stat_table[get_curr_dex(victim)].mod; if( trip < resist ) { act( AT_SKILL, "$n fails to trip you!", ch, NULL, victim, TO_VICT ); act( AT_SKILL, "You fail to trip $N!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n fails to trip $N!", ch, NULL, victim, TO_NOTVICT ); return; } if ( victim->mount ) { act( AT_SKILL, "$n trips your mount and you fall off!", ch, NULL, victim, TO_VICT ); act( AT_SKILL, "You trip $N's mount and $N falls off!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n trips $N's mount and $N falls off!", ch, NULL, victim, TO_NOTVICT ); REMOVE_BIT( victim->mount->act, ACT_MOUNTED ); victim->mount = NULL; victim->hit -= number_range(1, 5); update_pos(victim); WAIT_STATE( ch, 2 * PULSE_VIOLENCE ); WAIT_STATE( victim, 2 * PULSE_VIOLENCE ); victim->position = POS_RESTING; return; } if ( victim->wait == 0 ) { act( AT_SKILL, "$n trips you and you go down!", ch, NULL, victim, TO_VICT ); act( AT_SKILL, "You trip $N and $N goes down!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n trips $N and $N goes down!", ch, NULL, victim, TO_NOTVICT ); WAIT_STATE( ch, 2 * PULSE_VIOLENCE ); WAIT_STATE( victim, 2 * PULSE_VIOLENCE ); victim->position = POS_RESTING; } return; } void do_pick( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; int x, y; CHAR_DATA *victim; CHAR_DATA *gch; OBJ_DATA *obj; OBJ_DATA *iObj; EXIT_DATA *pexit; SHIP_DATA *ship; bool toolkit = FALSE; if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Pick what?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } for( iObj = ch->first_carrying; iObj; iObj = iObj->next_content ) { if( iObj->item_type == ITEM_TOOLKIT ) { toolkit = TRUE; break; } } if( !toolkit ) { send_to_char( "How are you going to do that without tools?\n\r", ch ); return; } WAIT_STATE( ch, PULSE_PER_SECOND*2 ); for ( gch = ch->in_room->first_person; gch; gch = gch->next_in_room ) { if ( IS_NPC(gch) && IS_AWAKE(gch) && ch->top_level < gch->top_level ) { act( AT_PLAIN, "$N is standing too close to the lock.", ch, NULL, gch, TO_CHAR ); return; } } if ( ( pexit = find_door( ch, arg, TRUE ) ) != NULL ) { EXIT_DATA *pexit_rev; if ( !IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( pexit->key < 0 ) { send_to_char( "It can't be picked.\n\r", ch ); return; } if ( !IS_SET(pexit->exit_info, EX_LOCKED) ) { send_to_char( "It's already unlocked.\n\r", ch ); return; } if ( IS_SET(pexit->exit_info, EX_PICKPROOF) ) { send_to_char( "You failed.\n\r", ch ); check_room_for_traps( ch, TRAP_PICK | trap_door[pexit->vdir] ); return; } x = skill_roll( ch, DISABLE_DEVICE ); if ( x < 20 ) { send_to_char( "You failed to disable the lock.\n\r", ch); return; } REMOVE_BIT(pexit->exit_info, EX_LOCKED); send_to_char( "You override the locking mechanism!\n\r", ch ); act( AT_ACTION, "$n overrides the lock of the $d.", ch, NULL, pexit->keyword, TO_ROOM ); /* pick the other side */ if ( ( pexit_rev = pexit->rexit ) != NULL && pexit_rev->to_room == ch->in_room ) { REMOVE_BIT( pexit_rev->exit_info, EX_LOCKED ); } check_room_for_traps( ch, TRAP_PICK | trap_door[pexit->vdir] ); return; } if ( ( obj = get_obj_here( ch, arg ) ) != NULL ) { if ( obj->item_type != ITEM_CONTAINER ) { send_to_char( "You can't pick that.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( obj->value[2] < 0 ) { send_to_char( "It can't be unlocked.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_LOCKED) ) { send_to_char( "It's already unlocked.\n\r", ch ); return; } if ( IS_SET(obj->value[1], CONT_PICKPROOF) ) { send_to_char( "You failed.\n\r", ch ); check_for_trap( ch, obj, TRAP_PICK ); return; } x = skill_roll( ch, DISABLE_DEVICE ); if ( x < 15 ) { send_to_char( "You failed to disable the locking mechanism.\n\r", ch); return; } separate_obj( obj ); REMOVE_BIT(obj->value[1], CONT_LOCKED); send_to_char( "You disable the locking mechanism!\n\r", ch ); act( AT_ACTION, "$n disables the lock of the $p.", ch, obj, NULL, TO_ROOM ); check_for_trap( ch, obj, TRAP_PICK ); return; } if ( ( ship = ship_in_room(ch->in_room, arg ) ) != NULL ) { if ( check_pilot( ch , ship ) ) { send_to_char("&RWhat would be the point of that!\n\r",ch); return; } if ( ship->shipstate != SHIP_DOCKED && ship->shipstate != SHIP_DISABLED ) { send_to_char( "&RThat ship has already started to launch",ch); return; } WAIT_STATE( ch, PULSE_PER_SECOND*2 ); y = skill_roll( ch, DISABLE_DEVICE ); if ( y < 25 ) { send_to_char( "You failed to override the ships locking mechanism.\n\r", ch); if (ship->alarm >= 1) if((victim = get_char_world_ooc(ch, ship->owner)) != NULL) ch_printf(victim, "&RYou have received a signal from the alarm module installed in %s.&W", ship->name); return; } if ( !ship->hatchopen) { ship->hatchopen = TRUE; act( AT_PLAIN, "You pick the lock and open the hatch on $T.", ch, NULL, ship->name, TO_CHAR ); act( AT_PLAIN, "$n picks open the hatch on $T.", ch, NULL, ship->name, TO_ROOM ); echo_to_room( AT_YELLOW , get_room_index(ship->entrance) , "The hatch opens from the outside." ); } return; } ch_printf( ch, "You see no %s here.\n\r", arg ); return; } void do_sneak( CHAR_DATA *ch, char *argument ) { AFFECT_DATA af; if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } send_to_char( "You attempt to move silently.\n\r", ch ); affect_strip( ch, gsn_sneak ); af.type = gsn_sneak; af.duration = ch->top_level * DUR_CONV; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SNEAK; affect_to_char( ch, &af ); return; } void do_hide( CHAR_DATA *ch, char *argument ) { if ( IS_NPC(ch) && IS_AFFECTED( ch, AFF_CHARM ) ) { send_to_char( "You can't concentrate enough for that.\n\r", ch ); return; } if ( ch->mount ) { send_to_char( "You can't do that while mounted.\n\r", ch ); return; } send_to_char( "You attempt to hide.\n\r", ch ); if ( IS_NPC(ch) || number_percent( ) < 0 ) SET_BIT(ch->affected_by, AFF_HIDE); return; } void do_visible( CHAR_DATA *ch, char *argument ) { affect_strip ( ch, gsn_sneak ); REMOVE_BIT ( ch->affected_by, AFF_HIDE ); REMOVE_BIT ( ch->affected_by, AFF_INVISIBLE ); REMOVE_BIT ( ch->affected_by, AFF_SNEAK ); send_to_char( "You become more visible.\n\r", ch ); return; } void do_recall( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *location; CHAR_DATA *opponent; location = NULL; location = get_room_index( wherehome(ch) ); if ( get_trust( ch ) < LEVEL_IMMORTAL ) { AREA_DATA * pArea; if ( !ch->pcdata || !(pArea=ch->pcdata->area) ) { send_to_char( "Only builders can recall.\n\r", ch ); return; } if ( ch->in_room->vnum < pArea->low_r_vnum || ch->in_room->vnum > pArea->hi_r_vnum ) { send_to_char( "You can only recall from your assigned area.\n\r", ch ); return; } } if ( !location ) { send_to_char( "You are completely lost.\n\r", ch ); return; } if ( ch->in_room == location ) return; if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) ) { send_to_char( "For some strange reason... nothing happens.\n\r", ch ); return; } if ( ( opponent = who_fighting( ch ) ) != NULL ) { if ( number_bits( 1 ) == 0 || ( !IS_NPC( opponent ) && number_bits( 3 ) > 1 ) ) { WAIT_STATE( ch, 4 ); ch_printf( ch, "You failed!\n\r" ); return; } ch_printf( ch, "You recall from combat!\n\r" ); stop_fighting( ch, TRUE ); } act( AT_ACTION, "$n disappears in a swirl of the Force.", ch, NULL, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, location ); if ( ch->mount ) { char_from_room( ch->mount ); char_to_room( ch->mount, location ); } act( AT_ACTION, "$n appears in a swirl of the Force.", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); return; } void do_aid( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; OBJ_DATA *obj; int chance, heal; bool has_toolkit = FALSE; bool has_medpac = FALSE; if( !IS_AWAKE(ch) || ch->position == POS_FIGHTING ) { send_to_char( "Not in this current position.\n\r", ch ); return; } if( ch->mount ) { send_to_char( "Not while mounted.\n\r", ch ); return; } if( argument[0] == '\0' ) { send_to_char( "Offer aid to whom?\n\r", ch ); return; } if( ( victim = get_char_room( ch, argument ) ) == NULL ) { send_to_char( "I don't see them here.\n\r", ch ); return; } if( victim->hit >= victim->max_hit ) { send_to_char( "They don't need your assistance.\n\r", ch ); return; } if( IS_DROID(victim) ) { for( obj = ch->first_carrying; obj; obj = obj->next_content ) { if( obj->item_type == ITEM_TOOLKIT ) { has_toolkit = TRUE; break; } } if( !has_toolkit ) { send_to_char( "How are you going to repair a droid without a toolkit?\n\r", ch ); return; } chance = skill_roll( ch, REPAIR_SKILL ); WAIT_STATE( ch, PULSE_VIOLENCE ); if( chance < 15 ) { act( AT_ACTION, "You fail to repair $N.\n\r", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n fails to repair you.\n\r", ch, NULL, victim, TO_VICT ); act( AT_ACTION, "$n fails to repair $N.\n\r", ch, NULL, victim, TO_NOTVICT ); return; } heal = number_range(2, 9); if( chance >= 15 && chance < 20 ) heal += 2; else if( chance >= 20 ) heal += 5; victim->hit = URANGE( victim->hit, victim->hit + heal, victim->max_hit ); update_pos(victim); act( AT_ACTION, "You repair $N.\n\r", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n repairs you.\n\r", ch, NULL, victim, TO_VICT ); act( AT_ACTION, "$n repairs $N.\n\r", ch, NULL, victim, TO_NOTVICT ); return; } for( obj = ch->first_carrying; obj; obj = obj->next_content ) { if( obj->item_type == ITEM_MEDPAC ) { has_medpac = TRUE; break; } } if( !has_medpac ) { send_to_char( "How are you going to be of any use without a medpac.\n\r", ch ); return; } separate_obj( obj ); obj_from_char( obj ); chance = skill_roll( ch, TREAT_INJURY ); WAIT_STATE( ch, PULSE_VIOLENCE ); if( chance < 15 ) { if( ch != victim ) { act( AT_ACTION, "You fail to aid $N.\n\r", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n fails to aid you.\n\r", ch, NULL, victim, TO_VICT ); act( AT_ACTION, "$n fails to aid $N.\n\r", ch, NULL, victim, TO_NOTVICT ); return; } act( AT_ACTION, "You fail to aid yourself.\n\r", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n fails to aid $mself.\n\r", ch, NULL, victim, TO_NOTVICT ); return; } heal = ( number_range(1, 10) + (4 * obj->value[0]) ); victim->hit = URANGE( victim->hit, victim->hit + heal, victim->max_hit ); update_pos(victim); if( ch != victim ) { act( AT_ACTION, "You aid $N.\n\r", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n aids you slightly.\n\r", ch, NULL, victim, TO_VICT ); act( AT_ACTION, "$n aids $N slightly.\n\r", ch, NULL, victim, TO_NOTVICT ); return; } act( AT_ACTION, "You aid yourself.\n\r", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n aids $mself.\n\r", ch, NULL, victim, TO_NOTVICT ); return; } void do_mount( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; int chance; if ( ch->mount ) { send_to_char( "You're already mounted!\n\r", ch ); return; } if ( ( victim = get_char_room( ch, argument ) ) == NULL ) { send_to_char( "You can't find that here.\n\r", ch ); return; } if ( !IS_NPC(victim) || !IS_SET(victim->act, ACT_MOUNTABLE ) ) { send_to_char( "You can't mount that!\n\r", ch ); return; } if ( IS_SET(victim->act, ACT_MOUNTED ) ) { send_to_char( "That mount already has a rider.\n\r", ch ); return; } if ( victim->position < POS_STANDING ) { send_to_char( "Your mount must be standing.\n\r", ch ); return; } if ( victim->position == POS_FIGHTING || victim->fighting ) { send_to_char( "Your mount is moving around too much.\n\r", ch ); return; } chance = skill_roll( ch, RIDE_SKILL ); WAIT_STATE( ch, PULSE_PER_SECOND*2 ); if ( chance >= 10 ) { SET_BIT( victim->act, ACT_MOUNTED ); ch->mount = victim; act( AT_SKILL, "You mount $N.", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n skillfully mounts $N.", ch, NULL, victim, TO_NOTVICT ); act( AT_SKILL, "$n mounts you.", ch, NULL, victim, TO_VICT ); ch->position = POS_MOUNTED; } else { act( AT_SKILL, "You unsuccessfully try to mount $N.", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n unsuccessfully attempts to mount $N.", ch, NULL, victim, TO_NOTVICT ); act( AT_SKILL, "$n tries to mount you.", ch, NULL, victim, TO_VICT ); } return; } void do_dismount( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; int chance; if ( (victim = ch->mount) == NULL ) { send_to_char( "You're not mounted.\n\r", ch ); return; } chance = skill_roll( ch, RIDE_SKILL ); WAIT_STATE( ch, PULSE_PER_SECOND*2 ); if ( chance >= 10 ) { act( AT_SKILL, "You dismount $N.", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n skillfully dismounts $N.", ch, NULL, victim, TO_NOTVICT ); act( AT_SKILL, "$n dismounts you. Whew!", ch, NULL, victim, TO_VICT ); REMOVE_BIT( victim->act, ACT_MOUNTED ); ch->mount = NULL; ch->position = POS_STANDING; } else { act( AT_SKILL, "You fall off while dismounting $N. Ouch!", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n falls off of $N while dismounting.", ch, NULL, victim, TO_NOTVICT ); act( AT_SKILL, "$n falls off your back.", ch, NULL, victim, TO_VICT ); REMOVE_BIT( victim->act, ACT_MOUNTED ); ch->mount = NULL; ch->position = POS_SITTING; global_retcode = damage( ch, ch, 1, TYPE_UNDEFINED, FALSE ); } return; } bool check_parry( CHAR_DATA *ch, CHAR_DATA *victim ) { return FALSE; } void do_rage( CHAR_DATA *ch, char *argument ) { AFFECT_DATA af; if ( !IS_NPC(ch) && !HAS_FFEAT( ch, RAGE_FEAT ) ) { send_to_char( "Huh?\n\r", ch ); return; } if ( !ch->fighting ) { send_to_char( "But you aren't fighting!\n\r", ch ); return; } if ( IS_AFFECTED(ch, AFF_RAGE ) ) { send_to_char( "Your rage is already at its peak!\n\r", ch ); return; } gain_darkpoint( ch ); WAIT_STATE(ch, PULSE_PER_SECOND*3 ); af.type = gsn_rage; af.duration = (20 * stat_table[get_curr_con(ch)].mod); af.location = APPLY_STR; af.modifier = 4; af.bitvector = AFF_RAGE; affect_to_char(ch, &af); af.type = gsn_rage; af.duration = (20 * stat_table[get_curr_con(ch)].mod); af.location = APPLY_FORT; af.modifier = 2; af.bitvector = AFF_RAGE; affect_to_char(ch, &af); af.type = gsn_rage; af.duration = (20 * stat_table[get_curr_con(ch)].mod); af.location = APPLY_WILL; af.modifier = 2; af.bitvector = AFF_RAGE; affect_to_char(ch, &af); af.type = gsn_rage; af.duration = (20 * stat_table[get_curr_con(ch)].mod); af.location = APPLY_AC; af.modifier = -2; af.bitvector = AFF_RAGE; affect_to_char(ch, &af); af.type = gsn_rage; af.duration = (20 * stat_table[get_curr_con(ch)].mod); af.location = APPLY_HIT; af.modifier = (2 * ch->top_level); af.bitvector = AFF_RAGE; affect_to_char(ch, &af); send_to_char( "You start to lose control..\n\r", ch ); return; } bool check_illegal_psteal( CHAR_DATA *ch, CHAR_DATA *victim ) { return FALSE; } void do_scan( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *was_in_room; ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; OBJ_DATA *goggles; sh_int dir = -1; sh_int dist; sh_int max_dist = 3; if ( argument[0] == '\0' ) { send_to_char( "Scan in a direction...\n\r", ch ); return; } if ( ( dir = get_door( argument ) ) == -1 ) { send_to_char( "Scan in WHAT direction?\n\r", ch ); return; } was_in_room = ch->in_room; act( AT_GREY, "Scanning $t...", ch, dir_name[dir], NULL, TO_CHAR ); act( AT_GREY, "$n scans $t.", ch, dir_name[dir], NULL, TO_ROOM ); if ( ( pexit = get_exit( ch->in_room, dir ) ) == NULL ) { act( AT_GREY, "You can't see $t.", ch, dir_name[dir], NULL, TO_CHAR ); return; } goggles = get_eq_char(ch, WEAR_EYES); if( goggles != NULL && goggles->item_type == ITEM_GOGGLES) { if(goggles->value[4] != 0) max_dist = goggles->value[4]; } for ( dist = 1; dist <= max_dist; ) { if ( IS_SET( pexit->exit_info, EX_CLOSED ) ) { if ( IS_SET( pexit->exit_info, EX_SECRET ) ) act( AT_GREY, "Your view $t is blocked by a wall.", ch, dir_name[dir], NULL, TO_CHAR ); else act( AT_GREY, "Your view $t is blocked by a door.", ch, dir_name[dir], NULL, TO_CHAR ); break; } to_room = NULL; if ( pexit->distance > 1 ) to_room = generate_exit( ch->in_room , &pexit ); if ( to_room == NULL ) to_room = pexit->to_room; if ( room_is_private( ch, to_room ) && get_trust(ch) < LEVEL_GREATER ) { act( AT_GREY, "Your view $t is blocked by a private room.", ch, dir_name[dir], NULL, TO_CHAR ); break; } char_from_room( ch ); char_to_room( ch, to_room ); set_char_color( AT_RMNAME, ch ); send_to_char( ch->in_room->name, ch ); send_to_char( "\n\r", ch ); show_list_to_char( ch->in_room->first_content, ch, FALSE, FALSE ); show_char_to_char( ch->in_room->first_person, ch ); dist++; if ( dist >= max_dist ) { act( AT_GREY, "Your vision blurs with distance and you see no " "farther $t.", ch, dir_name[dir], NULL, TO_CHAR ); break; } if ( ( pexit = get_exit( ch->in_room, dir ) ) == NULL ) { act( AT_GREY, "Your view $t is blocked by a wall.", ch, dir_name[dir], NULL, TO_CHAR ); break; } } char_from_room( ch ); char_to_room( ch, was_in_room ); return; } void do_plantcamera( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; ROOM_INDEX_DATA *room; CHAR_DATA *gch; AREA_DATA *area; char arg[MAX_INPUT_LENGTH]; bool has_camera; bool has_toolkit; bool not_alone; bool not_linked; int chance; strcpy( arg , argument ); switch( ch->substate ) { default: if ( IS_NPC(ch) ) return; has_camera = FALSE; has_toolkit = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if( obj->item_type == ITEM_TOOLKIT ) has_toolkit = TRUE; if( obj->item_type == ITEM_CAMERA ) has_camera = TRUE; } if ( !has_toolkit ) { send_to_char( "&RYou must possess a toolkit in order to do this.&w\n\r", ch ); return; } if ( !has_camera ) { send_to_char( "&RYou lack a camera.&w\n\r", ch ); return; } if ( ( room = get_room_index( ch->in_room->vnum ) ) == NULL ) { send_to_char( "You aren't in a valid room. Notify an IMM.\n\r", ch ); return; } not_alone = FALSE; for ( gch = ch->in_room->first_person; gch; gch = gch->next ) { if( IS_IMMORTAL(ch) ) break; if( gch == ch ) continue; if( IS_NPC(gch) || !is_same_group( ch, gch ) ) not_alone = TRUE; } if ( not_alone ) { send_to_char( "&RYou require more privacy for this.&w\n\r", ch ); return; } chance = 0; chance = IS_NPC(ch) ? ch->top_level : ( ch->skill_level[SLEIGHT_OF_HAND] + stat_table[get_curr_dex(ch)].mod + number_range(1,20) ); if ( chance >= 20 ) { send_to_char( "&GYou begin to install a camera.\n\r", ch); act( AT_PLAIN, "$N takes $S tools and starts to install a camera.", NULL, NULL, ch, TO_NOTVICT ); add_timer ( ch , TIMER_DO_FUN , 25 , do_plantcamera, 1 ); ch->dest_buf = str_dup(arg); return; } send_to_char( "&RYou can't figure out how to plant this camera.&w\n\r", ch ); return; case 1: if ( !ch->dest_buf ) return; strcpy(arg, ch->dest_buf); DISPOSE( ch->dest_buf); break; case SUB_TIMER_DO_ABORT: DISPOSE( ch->dest_buf ); ch->substate = SUB_NONE; send_to_char("&RYou are interupted and fail to finish your work.\n\r", ch); return; } ch->substate = SUB_NONE; has_toolkit = FALSE; has_camera = FALSE; not_alone = FALSE; not_linked = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if ( obj->item_type == ITEM_TOOLKIT ) has_toolkit = TRUE; if ( obj->item_type == ITEM_CAMERA && has_camera == FALSE ) { if( obj->value[0] == 0 ) { not_linked = TRUE; continue; } separate_obj( obj ); obj_from_char( obj ); extract_obj( obj ); has_camera = TRUE; } } if ( !has_camera && not_linked ) { send_to_char( "&GYou must first link the camera to a monitor.&w\n\r", ch ); return; } room = get_room_index( ch->in_room->vnum ); if ( !room ) { send_to_char( "&RNotify an IMM.&w\n\r", ch ); return; } for ( gch = ch->in_room->first_person; gch; gch = gch->next ) { if( IS_IMMORTAL(ch) ) break; if( ch == gch ) continue; if( IS_NPC(gch) || !is_same_group( ch, gch ) ) not_alone = TRUE; } if ( not_alone ) { send_to_char( "&RSome has come and disturbed your work.&w\n\r", ch ); return; } chance = 0; chance = IS_NPC(ch) ? ch->top_level : ( ch->skill_level[SLEIGHT_OF_HAND] + stat_table[get_curr_dex(ch)].mod + number_range(1,20) ); if( !has_camera || !has_toolkit || ( 15 > chance ) ) { send_to_char( "&GYou finish installing a new camera, only to realize you've destroyed it.&w\n\r", ch ); return; } area = ch->in_room->area; if( !area ) { send_to_char( "&GCould not add reset. Inform an IMM.&w\n\r", ch ); return; } add_obj_reset( area, 'O', obj, 1, ch->in_room->vnum ); SET_BIT( obj->extra_flags, ITEM_INSTALLED ); obj_to_room( obj, room ); send_to_char( "&GYou successfully installed a camera.&w\n\r", ch ); act( AT_GREEN, "$N has finished $S work.&w\n\r", NULL, NULL, ch, TO_NOTVICT ); return; } void do_plantmonitor( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; ROOM_INDEX_DATA *room; CHAR_DATA *gch; AREA_DATA *area; char arg[MAX_INPUT_LENGTH]; bool has_monitor; bool has_toolkit; bool not_alone; bool not_linked; int chance; strcpy( arg , argument ); switch( ch->substate ) { default: if ( IS_NPC(ch) ) return; has_monitor = FALSE; has_toolkit = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if( obj->item_type == ITEM_TOOLKIT ) has_toolkit = TRUE; if( obj->item_type == ITEM_MONITOR ) has_monitor = TRUE; } if ( !has_toolkit ) { send_to_char( "&RYou must possess a toolkit in order to do this.&w\n\r", ch ); return; } if ( !has_monitor ) { send_to_char( "&RYou lack a monitor.&w\n\r", ch ); return; } if ( ( room = get_room_index( ch->in_room->vnum ) ) == NULL ) { send_to_char( "You aren't in a valid room. Notify an IMM.\n\r", ch ); return; } not_alone = FALSE; for ( gch = ch->in_room->first_person; gch; gch = gch->next ) { if( IS_IMMORTAL(ch) ) break; if( gch == ch ) continue; if( IS_NPC(gch) || !is_same_group( ch, gch ) ) not_alone = TRUE; } if ( not_alone ) { send_to_char( "&RYou require more privacy for this.&w\n\r", ch ); return; } chance = 0; chance = IS_NPC(ch) ? ch->top_level : ( ch->skill_level[SLEIGHT_OF_HAND] + stat_table[get_curr_dex(ch)].mod + number_range(1,20) ); if ( chance >= 20 ) { send_to_char( "&GYou begin to install a monitor.\n\r", ch); act( AT_PLAIN, "$N takes $S tools and starts to install a monitor.", NULL, NULL, ch, TO_NOTVICT ); add_timer ( ch , TIMER_DO_FUN , 25 , do_plantmonitor, 1 ); ch->dest_buf = str_dup(arg); return; } send_to_char( "&RYou can't figure out how to plant this monitor.&w\n\r", ch ); return; case 1: if ( !ch->dest_buf ) return; strcpy(arg, ch->dest_buf); DISPOSE( ch->dest_buf); break; case SUB_TIMER_DO_ABORT: DISPOSE( ch->dest_buf ); ch->substate = SUB_NONE; send_to_char("&RYou are interupted and fail to finish your work.\n\r", ch); return; } ch->substate = SUB_NONE; has_toolkit = FALSE; has_monitor = FALSE; not_alone = FALSE; not_linked = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if ( obj->item_type == ITEM_TOOLKIT ) has_toolkit = TRUE; if ( obj->item_type == ITEM_MONITOR && has_monitor == FALSE ) { separate_obj( obj ); obj_from_char( obj ); extract_obj( obj ); has_monitor = TRUE; } } room = get_room_index( ch->in_room->vnum ); if ( !room ) { send_to_char( "&RNotify an IMM.&w\n\r", ch ); return; } for ( gch = ch->in_room->first_person; gch; gch = gch->next ) { if( IS_IMMORTAL(ch) ) break; if( ch == gch ) continue; if( IS_NPC(gch) || !is_same_group( ch, gch ) ) not_alone = TRUE; } if ( not_alone ) { send_to_char( "&RSome has come and disturbed your work.&w\n\r", ch ); return; } chance = 0; chance = IS_NPC(ch) ? ch->top_level : ( ch->skill_level[SLEIGHT_OF_HAND] + stat_table[get_curr_dex(ch)].mod + number_range(1,20) ); if( !has_monitor || !has_toolkit || ( 15 > chance ) ) { send_to_char( "&GYou finish installing a new monitor, only to realize you've destroyed it.&w\n\r", ch ); return; } area = ch->in_room->area; if( !area ) { send_to_char( "&GCould not add reset. Inform an IMM.&w\n\r", ch ); return; } add_obj_reset( area, 'O', obj, 1, room->vnum ); SET_BIT( obj->extra_flags, ITEM_INSTALLED ); obj_to_room( obj, room ); send_to_char( "&GYou successfully installed a monitor.&w\n\r", ch ); act( AT_GREEN, "$N has finished $S work.&w\n\r", NULL, NULL, ch, TO_NOTVICT ); return; } void do_linkcamera( CHAR_DATA *ch, char *argument ) { OBJ_DATA *camera; OBJ_DATA *monitor; OBJ_DATA *obj; if( IS_NPC(ch) || argument[0] == '\0' ) { send_to_char( "&GSyntax: &w&WLinkcamera <camera>&w\n\r", ch ); return; } if( ( camera = get_obj_carry( ch, argument ) ) == NULL ) { send_to_char( "You do not have that camera.\n\r", ch ); return; } for ( obj = ch->in_room->first_content; obj; obj = obj->next ) { if( obj->item_type == ITEM_MONITOR ) { monitor = obj; break; } } if( !monitor ) { send_to_char( "&RThere is no monitor here to link to.&w\n\r", ch ); return; } camera->value[0] = ch->in_room->vnum; act( AT_GREEN, "You link a camera to $p.\n\r", ch, monitor, NULL, TO_CHAR ); act( AT_GREEN, "$n links a camera to $p.\n\r", ch, monitor, NULL, TO_NOTVICT ); return; } void do_tunemonitor( CHAR_DATA *ch, char *argument ) { AREA_DATA *area; ROOM_INDEX_DATA *in_room; ROOM_INDEX_DATA *iRoom; OBJ_DATA *monitor; OBJ_DATA *camera; char buf[MAX_STRING_LENGTH]; bool has_monitor=FALSE; bool has_camera=FALSE; int room; int chance=0; if( IS_NPC(ch) ) return; in_room = get_room_index( ch->in_room->vnum ); if( !in_room ) { send_to_char( "&RYou are not in a room. Inform an IMM.&w\n\r", ch ); return; } area = in_room->area; if( !area ) { send_to_char( "&RYour room is not linked to an Area. Inform an IMM.&w\n\r", ch ); return; } for( monitor = in_room->first_content; monitor; monitor = monitor->next ) { if( monitor->item_type == ITEM_MONITOR && IS_SET(monitor->extra_flags, ITEM_INSTALLED) ) { has_monitor = TRUE; break; } } if( !has_monitor ) { send_to_char( "&RThere is no monitor here to tune.&w\n\r", ch ); return; } chance = ( number_range(1,20) + ch->skill_level[COMPUTER_SKILL] + stat_table[get_curr_int(ch)].mod ); if( chance < 17 ) { sprintf( buf, "%s beeps in error.", monitor->name ); act( AT_GREEN, buf, ch, NULL, NULL, TO_CHAR ); act( AT_GREEN, buf, ch, NULL, NULL, TO_ROOM ); return; } for( room = area->low_r_vnum; room < area->hi_r_vnum; room++ ) { if( ( iRoom = get_room_index( room ) ) == NULL ) continue; if( iRoom->vnum <= in_room->vnum ) continue; for( camera = iRoom->first_content; camera; camera = camera->next ) if( camera->item_type == ITEM_CAMERA && camera->value[0] == in_room->vnum ) { has_camera = TRUE; break; } } if( !has_camera ) { for( room = area->low_r_vnum; room < area->hi_r_vnum; room++ ) { if( ( iRoom = get_room_index( room ) ) == NULL ) continue; if( iRoom->vnum == in_room->vnum ) continue; for( camera = iRoom->first_content; camera; camera = camera->next ) { if( camera->item_type == ITEM_CAMERA && camera->value[0] == in_room->vnum ) { has_camera = TRUE; break; } } } } if( !has_camera ) { send_to_char( "&RThere are no cameras linked to this monitor.&w\n\r", ch ); return; } monitor->pIndexData->value[0] = iRoom->vnum; sprintf( buf, "%s beeps as it locks into a cameras signal.", monitor->name ); act( AT_GREEN, buf, ch, monitor, NULL, TO_CHAR ); act( AT_GREEN, buf, ch, monitor, NULL, TO_ROOM ); WAIT_STATE(ch, PULSE_VIOLENCE); return; } void do_checkmonitor( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *iRoom; OBJ_DATA *monitor; OBJ_DATA *camera; char buf[MAX_STRING_LENGTH]; bool has_monitor=FALSE; bool has_camera=FALSE; int chance; if( IS_NPC(ch) ) return; if( ch->position <= POS_SLEEPING ) { send_to_char( "&RYou can't do that while in your current position.&w\n\r", ch ); return; } for( monitor = ch->in_room->first_content; monitor; monitor = monitor->next ) { if( monitor->item_type == ITEM_MONITOR && IS_SET(monitor->extra_flags, ITEM_INSTALLED) ) { has_monitor = TRUE; break; } } if( !has_monitor ) { send_to_char( "&RI don't see a monitor here.&w\n\r", ch ); return; } iRoom = get_room_index( monitor->value[0] ); if( !iRoom ) { send_to_char( "&RThis monitor isn't linked to any cameras.&w\n\r", ch ); return; } for( camera = iRoom->first_content; camera; camera = camera->next ) { if( camera->item_type == ITEM_CAMERA && camera->value[0] == ch->in_room->vnum ) { has_camera = TRUE; break; } } if( !has_camera ) { send_to_char( "&RThis monitor isn't connected to any cameras.&w\n\r", ch ); return; } chance = ( number_range(1,20) + ch->skill_level[COMPUTER_SKILL] + stat_table[get_curr_int(ch)].mod ); if( chance < 17 ) { sprintf( buf, "%s beeps in error.", monitor->name ); act( AT_GREEN, buf, ch, monitor, NULL, TO_ROOM ); act( AT_GREEN, buf, ch, monitor, NULL, TO_CHAR ); WAIT_STATE( ch, PULSE_VIOLENCE ); return; } ch_printf(ch, "&R-=&r( &G&W%s &G&r)&R=-&C&w ", iRoom->name); if ( ! ch->desc->original ) { if ((get_trust(ch) >= LEVEL_IMMORTAL) && (IS_SET(ch->pcdata->flags, PCFLAG_ROOM))) { set_char_color(AT_BLUE, ch); send_to_char("{", ch); ch_printf(ch, "&G&W%d", iRoom->vnum); set_char_color(AT_BLUE, ch); send_to_char("}", ch); set_char_color(AT_CYAN, ch); send_to_char("[", ch); send_to_char(" ", ch); set_char_color(AT_WHITE, ch); send_to_char(flag_string(iRoom->room_flags, r_flags), ch); send_to_char(" ", ch); if( iRoom->room_flags2 != 0) { set_char_color(AT_DGREEN, ch); send_to_char(flag_string(iRoom->room_flags2, r_flags2), ch); send_to_char(" ", ch); } set_char_color(AT_CYAN, ch); send_to_char("]", ch); } } send_to_char( "\n\r", ch ); set_char_color( AT_RMDESC, ch ); if ( !IS_NPC(ch) && !IS_SET(ch->act, PLR_BRIEF) ) send_to_char( iRoom->description, ch ); if ( !IS_NPC(ch) && IS_SET(ch->act, PLR_AUTOEXIT) ) do_exits( ch, "" ); show_ships_to_char( iRoom->first_ship, ch ); show_list_to_char( iRoom->first_content, ch, FALSE, FALSE ); show_char_to_char( iRoom->first_person, ch ); return; }