const char *char_data::get_name( CHAR_DATA *looker ) { if ( looker != NULL ) { if ( can_see(looker, this) ) { if ( IS_NPC(this) ) return npcdata->short_descr; else { if ( IS_WOLF(this) && (IS_SHIFTED(this) || IS_RAGED(this)) ) return "A Large @@bWolf@@N"; else return name.c_str(); } } else { if ( IS_IMMORTAL(this) ) return "A Mystical Being"; else return "Someone"; } } else { if ( IS_NPC(this) ) return npcdata->short_descr; else return name.c_str(); } return "Unknown!"; }
/* * The main entry point for executing commands. * Can be recursively called from 'at', 'order', 'force'. */ void interpret( CHAR_DATA *ch, char *argument ) { /* BUG with aliases: they can call themselves, which is * a Bad Thing. When an alias calls interp, we'll add * a '~' char as the first char. Checking for this will * tell us if we need to check aliases again. -S- */ bool alias_call; char command[MAX_INPUT_LENGTH]; char logline[MAX_INPUT_LENGTH]; int cmd; int trust; bool found; alias_call = FALSE; if ( ch->position == POS_WRITING ) /* if player is writing, pass argument straight to write_interpret */ { write_interpret( ch, argument ); return; } if ( ch->position == POS_BUILDING ) { if (argument[0]==':') argument++; else { build_interpret(ch,argument); return; } } /* * Strip leading spaces. */ while ( isspace(*argument) ) argument++; if ( argument[0] == '\0' ) return; if ( argument[0] == '~' ) { argument++; alias_call = TRUE; } /* * No hiding. */ REMOVE_BIT( ch->affected_by, AFF_HIDE ); /* * Implement freeze command. */ if ( !IS_NPC(ch) && IS_SET(ch->act, PLR_FREEZE) ) { send_to_char( "@@a@@fYou're totally frozen!@@N\n\r", ch ); return; } if ( ch->stunTimer > 0 ) { send_to_char( "You are too@@aSTUNNED@@N to act!\n\r", ch ); return; } /* * Grab the command word. * Special parsing so ' can be a command, * also no spaces needed after punctuation. */ strcpy( logline, argument ); if ( !isalpha(argument[0]) && !isdigit(argument[0]) ) { command[0] = argument[0]; command[1] = '\0'; argument++; while ( isspace(*argument) ) argument++; } else { argument = one_argument( argument, command ); } /* * Look for command in command table. */ found = FALSE; trust = get_trust( ch ); for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ ) { /* Stephen Mod: if level == CLAN_ONLY then for clan member only. == BOSS_ONLY have to be leader. == -3 vamp == -4 wolf */ if ( cmd_table[cmd].level == CLAN_ONLY && !IS_NPC( ch ) && ch->pcdata->clan == 0 ) continue; if ( cmd_table[cmd].level == BOSS_ONLY && !IS_NPC( ch ) && !IS_SET( ch->pcdata->pflags, PFLAG_CLAN_BOSS ) ) continue; if ( cmd_table[cmd].level == VAMP_ONLY && !IS_NPC( ch ) && !IS_VAMP( ch ) && ( ch->level != L_GOD ) ) continue; if ( cmd_table[cmd].level == WOLF_ONLY && !IS_NPC( ch ) && !IS_WOLF( ch ) && ( ch->level != L_GOD ) ) continue; if ( command[0] == cmd_table[cmd].name[0] && !str_prefix( command, cmd_table[cmd].name ) && ( cmd_table[cmd].level <= trust || MP_Commands( ch ) ) ) { found = TRUE; break; } } /* * Log and snoop. */ if ( cmd_table[cmd].log == LOG_NEVER ) strcpy( logline, "XXXXXXXX XXXXXXXX XXXXXXXX@@N"); if ( ( !IS_NPC(ch) && IS_SET(ch->act, PLR_LOG) ) || fLogAll || cmd_table[cmd].log == LOG_ALWAYS ) { sprintf( log_buf, "Log %s: %s", ch->name, logline ); log_string( log_buf ); if ( IS_SET( ch->act, PLR_LOG ) ) monitor_chan( log_buf, MONITOR_BAD ); else if ( cmd_table[cmd].level > LEVEL_HERO ) monitor_chan( log_buf, MONITOR_GEN_IMM ); else monitor_chan( log_buf, MONITOR_GEN_MORT ); } if ( ch->desc != NULL && ch->desc->snoop_by != NULL ) /* -S- Mod */ { char snp[MAX_STRING_LENGTH]; sprintf( snp, "[Snoop:%s] %s\n\r", ch->name, logline ); write_to_buffer( ch->desc->snoop_by, snp, 0 ); } if ( !found && !IS_NPC( ch ) && (!alias_call) ) { int cnt; char foo[MAX_STRING_LENGTH]; /* Check aliases -S- */ for ( cnt = 0; cnt < MAX_ALIASES; cnt++ ) { if ( !str_cmp( ch->pcdata->alias_name[cnt], command ) && str_cmp( ch->pcdata->alias_name[cnt], "<none>@@N") ) { found = TRUE; sprintf( foo, "~%s %s", ch->pcdata->alias[cnt], argument ); interpret( ch, foo ); return; } } } if ( !found ) { /* * Look for command in socials table. */ if ( !check_social( ch, command, argument ) #ifdef IMC && !imc_command_hook( ch, command, argument ) #endif ) send_to_char( "Huh?\n\r", ch ); return; } /* * Character not in position for command? */ if ( ch->position < cmd_table[cmd].position ) { switch( ch->position ) { case POS_DEAD: send_to_char( "Lie still; you are @@dDEAD@@N.\n\r", ch ); break; case POS_MORTAL: case POS_INCAP: send_to_char( "You are @@Rhurt@@N far too bad for that.\n\r", ch ); break; case POS_STUNNED: send_to_char( "You are too @@estunned@@N to do that.\n\r", ch ); break; case POS_SLEEPING: send_to_char( "Oh, go back to @@Wsleep!@@N\n\r", ch ); break; case POS_RESTING: send_to_char( "Naaaaaah... You feel too @@brelaxed@@N...\n\r", ch); break; case POS_FIGHTING: send_to_char( "Not until you @@Rstop@@N fighting!\n\r", ch); break; } return; } /* * Dispatch the command. */ if ( !IS_NPC( ch ) && ( ( ch->stance == STANCE_AMBUSH ) || ( ch->stance == STANCE_AC_BEST ) ) && ( ( str_prefix( command, "kill" ) ) && ( str_prefix( command, "murder" ) ) && ( str_prefix( command, "backstab" ) ) && ( str_prefix( command, "bs" ) ) && ( str_prefix( command, "whisper" ) ) && ( str_prefix( command, "stake" ) ) && ( str_prefix( command, "steal" ) ) ) ) { send_to_char( "You step out of the shadows.\n\r", ch ); ch->stance = STANCE_WARRIOR; ch->stance_ac_mod = 0; ch->stance_dr_mod = 0; ch->stance_hr_mod = 0; act( "$n steps out of the Shadows!", ch, NULL, NULL, TO_ROOM ); } comlog(ch, cmd, argument); (*cmd_table[cmd].do_fun) ( ch, argument ); tail_chain( ); return; }
bool sp_damage( OBJ_DATA * obj, CHAR_DATA * ch, CHAR_DATA * victim, int dam, int type, int sn, bool show_msg ) { int ch_strong, ch_weak, ch_race, ch_suscept, ch_resist, vi_strong, vi_weak, vi_race, vi_suscept, vi_resist; float dam_modifier = 1.0; float tmp = 0; bool can_reflect = TRUE; bool can_absorb = TRUE; if ( victim == NULL ) return FALSE; /* * First, check caster's strengths and weaknesses. * */ if ( IS_SET( type, NO_REFLECT ) ) { REMOVE_BIT( type, NO_REFLECT ); can_reflect = FALSE; } if ( IS_SET( type, NO_ABSORB ) ) { REMOVE_BIT( type, NO_ABSORB ); can_absorb = FALSE; } if ( obj == NULL ) { if ( ( can_reflect ) && ( skill_table[sn].target == TAR_CHAR_OFFENSIVE ) && ( IS_AFFECTED( victim, AFF_CLOAK_REFLECTION ) ) && ( ch != victim ) && ( number_percent( ) < ( victim->get_level("psuedo") - 70 ) ) ) { act( "@@N$n's @@lc@@el@@ro@@ya@@ak@@N glows brightly as $Nn's spell hits it, and the spell is reflected@@N!!", ch, victim, NULL, TO_ROOM ); act( "@@N$N's @@lc@@el@@ro@@ya@@ak@@N glows brightly, and reflects your spell back on you@@N!!", ch, NULL, victim, TO_CHAR ); act( "@@NYour @@lc@@el@@ro@@ya@@ak@@N glows brightly, and reflects the spell back on $N@@N!!!", victim, NULL, ch, TO_CHAR ); ( *skill_table[sn].spell_fun ) ( sn, 60, ch, ( void * )ch, NULL ); return FALSE; } else if ( ( can_reflect ) && ( skill_table[sn].target == TAR_CHAR_OFFENSIVE ) && ( IS_AFFECTED( victim, AFF_CLOAK_ABSORPTION ) ) && ( ch != victim ) && ( number_percent( ) < ( victim->get_level("psuedo") - 55 ) ) ) { int mana; mana = mana_cost( ch, sn ); victim->mana = UMIN( victim->max_mana, victim->mana + mana ); act( "@@N$n's @@lcloak@@N glows brightly as $N's spell hits it, then fades@@N!!", victim, NULL, ch, TO_ROOM ); act( "@@N$N's @@lcloak@@N glows brightly, and absorbs your spell@@N!!", ch, NULL, victim, TO_CHAR ); act( "@@NYour @@lcloak@@N glows brightly, and absorbs $N's spell@@N!!!", victim, NULL, ch, TO_CHAR ); return FALSE; } ch_strong = ( IS_NPC( ch ) ? ( ( ( ch->race > 0 ) && ( ch->race < MAX_RACE ) ) ? race_table[ch->race].strong_realms : ch->npcdata->strong_magic ) : race_table[ch->race].strong_realms ); ch_resist = ( IS_NPC( ch ) ? ( ( ( ch->race > 0 ) && ( ch->race < MAX_RACE ) ) ? race_table[ch->race].resist_realms : ch->npcdata->resist ) : race_table[ch->race].resist_realms ); ch_weak = ( IS_NPC( ch ) ? ( ( ( ch->race > 0 ) && ( ch->race < MAX_RACE ) ) ? race_table[ch->race].weak_realms : ch->npcdata->weak_magic ) : race_table[ch->race].weak_realms ); ch_suscept = ( IS_NPC( ch ) ? ( ( ( ch->race > 0 ) && ( ch->race < MAX_RACE ) ) ? race_table[ch->race].suscept_realms : ch->npcdata->suscept ) : race_table[ch->race].suscept_realms ); ch_race = ( IS_NPC( ch ) ? ( ( ( ch->race > 0 ) && ( ch->race < MAX_RACE ) ) ? race_table[ch->race].race_flags : ch->race_mods ) : race_table[ch->race].race_flags ); if ( IS_SET( ch_strong, type ) ) { dam_modifier += .35; } else if ( IS_SET( ch_weak, type ) ) { dam_modifier -= .35; } if ( IS_SET( ch_race, RACE_MOD_STRONG_MAGIC ) ) { dam_modifier += .25; } else if ( IS_SET( ch_race, RACE_MOD_WEAK_MAGIC ) ) { dam_modifier -= .25; } else if ( IS_SET( ch_race, RACE_MOD_NO_MAGIC ) ) { dam_modifier -= .50; } if ( ch->stance == STANCE_CASTER ) dam_modifier += .10; else if ( ch->stance == STANCE_WIZARD ) dam_modifier += .25; else if ( ch->stance == STANCE_MAGI ) dam_modifier += .30; if ( ( !IS_NPC( ch ) ) && ( !IS_SET( type, REALM_MIND ) ) ) { if ( ch->pcdata->learned[gsn_potency] > 0 ) { dam_modifier += ( get_curr_int( ch ) * ch->pcdata->learned[gsn_potency] / 5000 ); } if ( ch->pcdata->learned[gsn_thaumatergy] > 0 ) { dam_modifier += ( get_curr_int( ch ) * ch->pcdata->learned[gsn_thaumatergy] / 2500 ); } } if ( is_affected( ch, skill_lookup( "mystical focus" ) ) ) { dam_modifier += .5; } } /* obj == NULL */ else if ( obj->carried_by != NULL ) { ch = obj->carried_by; } else { snprintf( log_buf, (2 * MIL), "Error, object %s casting spell, but not carried by anyone.", obj->short_descr ); monitor_chan( log_buf, MONITOR_DEBUG ); return FALSE; } /* * Next, the victim * */ vi_strong = ( IS_NPC( victim ) ? ( ( ( victim->race > 0 ) && ( victim->race < MAX_RACE ) ) ? race_table[victim->race].strong_realms : victim->npcdata->strong_magic ) : race_table[victim->race].strong_realms ); vi_resist = ( IS_NPC( victim ) ? ( ( ( victim->race > 0 ) && ( victim->race < MAX_RACE ) ) ? race_table[victim->race].resist_realms : victim->npcdata->resist ) : race_table[victim->race].resist_realms ); vi_weak = ( IS_NPC( victim ) ? ( ( ( victim->race > 0 ) && ( victim->race < MAX_RACE ) ) ? race_table[victim->race].weak_realms : victim->npcdata->weak_magic ) : race_table[victim->race].weak_realms ); vi_suscept = ( IS_NPC( victim ) ? ( ( ( victim->race > 0 ) && ( victim->race < MAX_RACE ) ) ? race_table[victim->race].suscept_realms : victim->npcdata->suscept ) : race_table[victim->race].suscept_realms ); vi_race = ( IS_NPC( victim ) ? ( ( ( victim->race > 0 ) && ( victim->race < MAX_RACE ) ) ? race_table[victim->race].race_flags : victim->race_mods ) : race_table[victim->race].race_flags ); if ( IS_SET( vi_suscept, type ) ) { dam_modifier += .45; } else if ( IS_SET( vi_resist, type ) ) { dam_modifier -= .45; } else if ( IS_SET( vi_race, RACE_MOD_NO_MAGIC ) ) { dam_modifier -= .25; } if ( MAGIC_STANCE( ch ) ) dam_modifier += .15; if ( ( IS_SET( type, REALM_MIND ) ) && ( !HAS_MIND( victim ) ) ) dam_modifier = 0.0; else if ( ( ( IS_SET( type, REALM_IMPACT ) ) || ( IS_SET( type, REALM_ACID ) ) || ( IS_SET( type, REALM_GAS ) ) ) && ( !HAS_BODY( victim ) ) ) dam_modifier = 0.0; if ( ( IS_SET( type, REALM_POISON ) ) && ( IS_SET( vi_race, RACE_MOD_IMMUNE_POISON ) ) ) dam_modifier = 0.0; if ( ( IS_SET( type, REALM_DRAIN ) ) && ( IS_UNDEAD( victim ) ) ) dam_modifier = 0.0; tmp = dam; tmp *= dam_modifier; if ( check_charm_aff(ch, CHARM_AFF_MAGE) ) tmp *= ((100 + get_charm_bonus(ch, CHARM_AFF_MAGE)) / 100); dam = static_cast<int>(tmp); dam += number_range(static_cast<int>((dam * -0.10)), static_cast<int>((dam * 0.10))); /* Lets add a little randomness to things. --Kline */ if ( victim != ch ) { /* * Certain attacks are forbidden. * Most other attacks are returned. */ if ( is_safe( ch, victim ) ) return FALSE; if ( victim != ch->fighting ) check_killer( ch, victim ); if ( victim->position > POS_STUNNED ) { if ( victim->fighting == NULL ) set_fighting( victim, ch, FALSE ); victim->position = POS_FIGHTING; } if ( victim->position > POS_STUNNED ) { if ( ch->fighting == NULL ) { set_fighting( ch, victim, TRUE ); } /* * If victim is charmed, ch might attack victim's master. */ if ( IS_NPC( ch ) && IS_NPC( victim ) && IS_AFFECTED( victim, AFF_CHARM ) && victim->master != NULL && victim->master->in_room == ch->in_room && number_bits( 3 ) == 0 ) { stop_fighting( ch ); one_hit( ch, victim->master, TYPE_UNDEFINED ); } } /* * More charm stuff. */ if ( victim->master == ch ) stop_follower( victim ); /* * Inviso attacks ... not. */ if ( IS_AFFECTED( ch, AFF_INVISIBLE ) ) { affect_strip( ch, gsn_invis ); affect_strip( ch, gsn_mass_invis ); REMOVE_BIT( ch->affected_by, AFF_INVISIBLE ); act( "$n shimmers into existence.", ch, NULL, NULL, TO_ROOM ); } /* * Damage modifiers. */ if ( dam < 0 ) dam = 0; /* * Stop up any residual loopholes. */ if ( dam > sysdata.damcap ) { char buf[MAX_STRING_LENGTH]; snprintf( buf, MSL, "Spell: %d damage by %s, spell %s", dam, ( obj == NULL ) ? ch->get_name() : obj->short_descr, skill_table[sn].name ); if ( ch->level < 82 ) monitor_chan( buf, MONITOR_MAGIC ); log_f( "%s", buf ); dam = sysdata.damcap; } if ( ( show_msg ) && ( dam >= 0 ) ) sp_dam_message( obj, ch, victim, dam, type, sn ); } /* * Hurt the victim. * Inform the victim of his new state. */ victim->hit -= dam; if ( !IS_NPC(ch) ) { if ( dam > ch->pcdata->records->mdam_amt ) { send_to_char("@@yYou've broken your magical damage record!@@N\r\n", ch); ch->pcdata->records->mdam_amt = dam; ch->pcdata->records->mdam_gsn = sn; } } if ( !IS_NPC( victim ) ) check_adrenaline( victim, dam ); if ( !IS_NPC( victim ) && IS_WOLF( victim ) && ( dam > 350 ) ) do_rage( victim, "FORCE" ); update_pos( victim ); if ( ( IS_NPC( victim ) || !IS_VAMP( victim ) ) && !( deathmatch ) ) { switch ( victim->position ) { case POS_MORTAL: act( "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM ); send_to_char( "You are mortally wounded, and will die soon, if not aided.\r\n", victim ); break; case POS_INCAP: act( "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM ); send_to_char( "You are incapacitated and will slowly die, if not aided.\r\n", victim ); break; case POS_STUNNED: act( "$n is too stunned to do anything!", victim, NULL, NULL, TO_ROOM ); send_to_char( "You are too stunned to do anything!\r\n", victim ); break; case POS_DEAD: act( "$n is DEAD!!", victim, 0, 0, TO_ROOM ); send_to_char( "You have been KILLED!!\r\n\r\n", victim ); break; default: if ( dam > victim->max_hit / 4 ) send_to_char( "That really did HURT!\r\n", victim ); if ( victim->hit < victim->max_hit / 4 ) send_to_char( "You sure are BLEEDING!\r\n", victim ); break; } } /* end of if statement */ /* * Sleep spells and extremely wounded folks. */ if ( !IS_AWAKE( victim ) ) stop_fighting( victim ); /* * Payoff for killing things. */ if ( victim->position == POS_DEAD && ( IS_NPC( victim ) || !IS_VAMP( victim ) || ( deathmatch ) ) ) { group_gain( ch, victim ); /* * Sort out kill counts..... */ if ( !IS_NPC( ch ) ) { if ( !IS_NPC( victim ) ) ch->pcdata->records->pk++; else ch->pcdata->records->mk++; } if ( !IS_NPC( victim ) ) { if ( !IS_NPC( ch ) ) victim->pcdata->records->pd++; else victim->pcdata->records->md++; } if ( !IS_NPC( victim ) || victim->act.test(ACT_INTELLIGENT) ) { snprintf( log_buf, (2 * MIL), "%s killed by %s at %d", victim->get_name(), ch->get_name(), victim->in_room->vnum ); log_string( log_buf ); notify( log_buf, 82 ); /* * As level gain is no longer automatic, a dead char loses * * 1/2 their gained exp. -S- * * Fixed my bug here too, hehe! */ if ( victim->exp > 0 ) { int lose = (victim->exp / 2); lose *= -1; victim->gain_exp(lose); } } if ( IS_NPC( ch ) ) raw_kill( victim, "" ); else { char name_buf[MAX_STRING_LENGTH]; snprintf( name_buf, MSL, "%s", ch->name.c_str() ); raw_kill( victim, name_buf ); } if ( deathmatch && !IS_NPC( victim ) ) do_quit( victim, "" ); if ( IS_NPC( ch ) && IS_NPC( victim ) && ch->act.test(ACT_INTELLIGENT) ) { do_get( ch, "all corpse" ); do_sacrifice( ch, "corpse" ); } if ( !IS_NPC( ch ) && IS_NPC( victim ) ) { if ( ch->act.test(ACT_AUTOLOOT) ) do_get( ch, "all corpse" ); else do_look( ch, "in corpse" ); if ( ch->act.test(ACT_AUTOSAC) ) do_sacrifice( ch, "corpse" ); } return FALSE; } if ( victim == ch ) return TRUE; /* * Take care of link dead people. */ if ( !IS_NPC( victim ) && victim->desc == NULL ) { if ( number_range( 0, victim->wait ) == 0 ) { do_recall( victim, "" ); return TRUE; } } /* * Wimp out? */ if ( IS_NPC( victim ) && dam > 0 ) { if ( ( victim->act.test(ACT_WIMPY) && number_bits( 1 ) == 0 && victim->hit < victim->max_hit / 2 ) || ( IS_AFFECTED( victim, AFF_CHARM ) && victim->master != NULL && victim->master->in_room != victim->in_room ) ) do_flee( victim, "" ); } if ( !IS_NPC( victim ) && victim->hit > 0 && victim->hit <= victim->wimpy && victim->wait == 0 ) do_flee( victim, "" ); return TRUE; }