Esempio n. 1
0
void do_mposet( CHAR_DATA * ch, const char *argument )
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
	char buf[MAX_STRING_LENGTH];
	OBJ_DATA *obj;
	char outbuf[MAX_STRING_LENGTH];
	int value, tmp;

	/*
	 * A desc means switched.. too many loopholes if we allow that.. 
	 */
	if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ) || ch->desc )
	{
		send_to_char( "Huh?\r\n", ch );
		return;
	}

	smash_tilde( argument );

	argument = one_argument( argument, arg1 );
	argument = one_argument( argument, arg2 );
	mudstrlcpy( arg3, argument, MAX_INPUT_LENGTH );

	if ( !*arg1 )
	{
		progbug( "MpOset: no args", ch );
		return;
	}

	if ( ( obj = get_obj_here( ch, arg1 ) ) == NULL )
	{
		progbug( "MpOset: no object", ch );
		return;
	}

	if ( IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) )
	{
		progbug( "MpOset: can't set prototype items", ch );
		return;
	}
	separate_obj( obj );
	value = atoi( arg3 );

	if ( !str_cmp( arg2, "value0" ) || !str_cmp( arg2, "v0" ) )
	{
		obj->value[0] = value;
		return;
	}

	if ( !str_cmp( arg2, "value1" ) || !str_cmp( arg2, "v1" ) )
	{
		obj->value[1] = value;
		return;
	}

	if ( !str_cmp( arg2, "value2" ) || !str_cmp( arg2, "v2" ) )
	{
		obj->value[2] = value;
		return;
	}

	if ( !str_cmp( arg2, "value3" ) || !str_cmp( arg2, "v3" ) )
	{
		obj->value[3] = value;
		return;
	}

	if ( !str_cmp( arg2, "value4" ) || !str_cmp( arg2, "v4" ) )
	{
		obj->value[4] = value;
		return;
	}

	if ( !str_cmp( arg2, "value5" ) || !str_cmp( arg2, "v5" ) )
	{
		obj->value[5] = value;
		return;
	}

	if ( !str_cmp( arg2, "type" ) )
	{
		if ( !argument || argument[0] == '\0' )
		{
			progbug( "MpOset: no type", ch );
			return;
		}
		value = get_otype( argument );
		if ( value < 1 )
		{
			progbug( "MpOset: Invalid type", ch );
			return;
		}
		obj->item_type = ( short ) value;
		return;
	}

	if ( !str_cmp( arg2, "flags" ) )
	{
		if ( !argument || argument[0] == '\0' )
		{
			progbug( "MpOset: no flags", ch );
			return;
		}
		while ( argument[0] != '\0' )
		{
			argument = one_argument( argument, arg3 );
			value = get_oflag( arg3 );
			if ( value < 0 || value >= MAX_BITS )
				progbug( "MpOset: Invalid flag", ch );
			else
			{
				if ( value == ITEM_PROTOTYPE )
					progbug( "MpOset: can't set prototype flag", ch );
				else
					xTOGGLE_BIT( obj->extra_flags, value );
			}
		}
		return;
	}

	if ( !str_cmp( arg2, "wear" ) )
	{
		if ( !argument || argument[0] == '\0' )
		{
			progbug( "MpOset: no wear", ch );
			return;
		}
		while ( argument[0] != '\0' )
		{
			argument = one_argument( argument, arg3 );
			value = get_wflag( arg3 );
			if ( value < 0 || value > 31 )
				progbug( "MpOset: Invalid wear", ch );
			else
				TOGGLE_BIT( obj->wear_flags, 1 << value );
		}
		return;
	}

	if ( !str_cmp( arg2, "level" ) )
	{
		obj->level = value;
		return;
	}

	if ( !str_cmp( arg2, "weight" ) )
	{
		obj->weight = value;
		return;
	}

	if ( !str_cmp( arg2, "cost" ) )
	{
		obj->cost = value;
		return;
	}

	if ( !str_cmp( arg2, "timer" ) )
	{
		obj->timer = value;
		return;
	}

	if ( !str_cmp( arg2, "name" ) )
	{
		STRFREE( obj->name );
		obj->name = STRALLOC( arg3 );
		return;
	}

	if ( !str_cmp( arg2, "short" ) )
	{
		STRFREE( obj->short_descr );
		obj->short_descr = STRALLOC( arg3 );

		if ( obj == supermob_obj )
		{
			STRFREE( supermob->short_descr );
			supermob->short_descr = QUICKLINK( obj->short_descr );
		}

		/*
		 * Feature added by Narn, Apr/96 
		 * * If the item is not proto, add the word 'rename' to the keywords
		 * * if it is not already there.
		 */
		if ( str_infix( "mprename", obj->name ) )
		{
			snprintf( buf, MAX_STRING_LENGTH, "%s %s", obj->name, "mprename" );
			STRFREE( obj->name );
			obj->name = STRALLOC( buf );
		}
		return;
	}

	if ( !str_cmp( arg2, "long" ) )
	{
		STRFREE( obj->description );
		mudstrlcpy( buf, arg3, MAX_STRING_LENGTH );
		obj->description = STRALLOC( buf );
		return;
	}

	if ( !str_cmp( arg2, "actiondesc" ) )
	{
		if ( strstr( arg3, "%n" ) || strstr( arg3, "%d" ) || strstr( arg3, "%l" ) )
		{
			progbug( "MpOset: Illegal actiondesc", ch );
			return;
		}
		STRFREE( obj->action_desc );
		obj->action_desc = STRALLOC( arg3 );
		return;
	}

	if ( !str_cmp( arg2, "affect" ) )
	{
		AFFECT_DATA *paf;
		short loc;
		int bitv;

		argument = one_argument( argument, arg2 );
		if ( arg2[0] == '\0' || !argument || argument[0] == 0 )
		{
			progbug( "MpOset: Bad affect syntax", ch );
			send_to_char( "Usage: oset <object> affect <field> <value>\r\n", ch );
			return;
		}
		loc = get_atype( arg2 );
		if ( loc < 1 )
		{
			progbug( "MpOset: Invalid affect field", ch );
			return;
		}
		if ( loc >= APPLY_AFFECT && loc < APPLY_WEAPONSPELL )
		{
			bitv = 0;
			while ( argument[0] != '\0' )
			{
				argument = one_argument( argument, arg3 );
				if ( loc == APPLY_AFFECT )
					value = get_aflag( arg3 );
				else
					value = get_risflag( arg3 );
				if ( value < 0 || value > 31 )
					progbug( "MpOset: bad affect flag", ch );
				else
					SET_BIT( bitv, 1 << value );
			}
			if ( !bitv )
				return;
			value = bitv;
		}
		else
		{
			argument = one_argument( argument, arg3 );
			value = atoi( arg3 );
		}
		CREATE( paf, AFFECT_DATA, 1 );
		paf->type = -1;
		paf->duration = -1;
		paf->location = loc;
		paf->modifier = value;
		xCLEAR_BITS( paf->bitvector );
		paf->next = NULL;
		LINK( paf, obj->first_affect, obj->last_affect, next, prev );
		++top_affect;
		return;
	}

	if ( !str_cmp( arg2, "rmaffect" ) )
	{
		AFFECT_DATA *paf;
		short loc, count;

		if ( !argument || argument[0] == '\0' )
		{
			progbug( "MpOset: no rmaffect", ch );
			return;
		}
		loc = atoi( argument );
		if ( loc < 1 )
		{
			progbug( "MpOset: Invalid rmaffect", ch );
			return;
		}

		count = 0;

		for ( paf = obj->first_affect; paf; paf = paf->next )
		{
			if ( ++count == loc )
			{
				UNLINK( paf, obj->first_affect, obj->last_affect, next, prev );
				DISPOSE( paf );
				send_to_char( "Removed.\r\n", ch );
				--top_affect;
				return;
			}
		}
		progbug( "MpOset: rmaffect not found", ch );
		return;
	}

	/*
	 * save some finger-leather
	 */
	if ( !str_cmp( arg2, "ris" ) )
	{
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect resistant %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect immune %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect susceptible %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		return;
	}

	if ( !str_cmp( arg2, "r" ) )
	{
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect resistant %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		return;
	}

	if ( !str_cmp( arg2, "i" ) )
	{
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect immune %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		return;
	}
	if ( !str_cmp( arg2, "s" ) )
	{
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect susceptible %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		return;
	}

	if ( !str_cmp( arg2, "ri" ) )
	{
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect resistant %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect immune %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		return;
	}

	if ( !str_cmp( arg2, "rs" ) )
	{
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect resistant %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect susceptible %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		return;
	}

	if ( !str_cmp( arg2, "is" ) )
	{
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect immune %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		snprintf( outbuf, MAX_STRING_LENGTH, "%s affect susceptible %s", arg1, arg3 );
		do_mposet( ch, outbuf );
		return;
	}

	/*
	 * Make it easier to set special object values by name than number
	 *                  -Thoric
	 */
	tmp = -1;
	switch ( obj->item_type )
	{
		case ITEM_WEAPON:
			if ( !str_cmp( arg2, "weapontype" ) )
			{
				unsigned int x;

				value = -1;
				for ( x = 0; x < sizeof( attack_table ) / sizeof( attack_table[0] ); x++ )
					if ( !str_cmp( arg3, attack_table[x] ) )
						value = x;
				if ( value < 0 )
				{
					progbug( "MpOset: Invalid weapon type", ch );
					return;
				}
				tmp = 3;
				break;
			}
			if ( !str_cmp( arg2, "condition" ) )
				tmp = 0;
			break;
		case ITEM_ARMOR:
			if ( !str_cmp( arg2, "condition" ) )
				tmp = 3;
			if ( !str_cmp( arg2, "ac" ) )
				tmp = 1;
			break;
		case ITEM_SALVE:
			if ( !str_cmp( arg2, "slevel" ) )
				tmp = 0;
			if ( !str_cmp( arg2, "maxdoses" ) )
				tmp = 1;
			if ( !str_cmp( arg2, "doses" ) )
				tmp = 2;
			if ( !str_cmp( arg2, "delay" ) )
				tmp = 3;
			if ( !str_cmp( arg2, "spell1" ) )
				tmp = 4;
			if ( !str_cmp( arg2, "spell2" ) )
				tmp = 5;
			if ( tmp >= 4 && tmp <= 5 )
				value = skill_lookup( arg3 );
			break;
		case ITEM_SCROLL:
		case ITEM_POTION:
		case ITEM_PILL:
			if ( !str_cmp( arg2, "slevel" ) )
				tmp = 0;
			if ( !str_cmp( arg2, "spell1" ) )
				tmp = 1;
			if ( !str_cmp( arg2, "spell2" ) )
				tmp = 2;
			if ( !str_cmp( arg2, "spell3" ) )
				tmp = 3;
			if ( tmp >= 1 && tmp <= 3 )
				value = skill_lookup( arg3 );
			break;
		case ITEM_STAFF:
		case ITEM_WAND:
			if ( !str_cmp( arg2, "slevel" ) )
				tmp = 0;
			if ( !str_cmp( arg2, "spell" ) )
			{
				tmp = 3;
				value = skill_lookup( arg3 );
			}
			if ( !str_cmp( arg2, "maxcharges" ) )
				tmp = 1;
			if ( !str_cmp( arg2, "charges" ) )
				tmp = 2;
			break;
		case ITEM_CONTAINER:
			if ( !str_cmp( arg2, "capacity" ) )
				tmp = 0;
			if ( !str_cmp( arg2, "cflags" ) )
				tmp = 1;
			if ( !str_cmp( arg2, "key" ) )
				tmp = 2;
			break;
		case ITEM_SWITCH:
		case ITEM_LEVER:
		case ITEM_PULLCHAIN:
		case ITEM_BUTTON:
			if ( !str_cmp( arg2, "tflags" ) )
			{
				tmp = 0;
				value = get_trigflag( arg3 );
			}
			break;
	}
	if ( tmp >= 0 && tmp <= 3 )
	{
		obj->value[tmp] = value;
		return;
	}

	progbug( "MpOset: Invalid field", ch );
	return;
}
Esempio n. 2
0
/*
 * Hit one guy with a projectile.
 * Handles use of missile weapons (wield = missile weapon)
 * or thrown items/weapons
 */
ch_ret projectile_hit( char_data * ch, char_data * victim, obj_data * wield, obj_data * projectile, short dist )
{
   int vic_ac, thac0, plusris, diceroll, prof_bonus, prof_gsn = -1, proj_bonus, dt, pchance;
   double dam = 0;
   ch_ret retcode;

   if( !projectile )
      return rNONE;

   if( projectile->item_type == ITEM_PROJECTILE || projectile->item_type == ITEM_WEAPON )
   {
      dt = TYPE_HIT + projectile->value[3];
      if( wield )
         proj_bonus = number_range( wield->value[1], wield->value[2] );
      else
         proj_bonus = 0;
   }
   else
   {
      dt = TYPE_UNDEFINED;
      proj_bonus = 0;
   }

   /*
    * Can't beat a dead char!
    */
   if( victim->position == POS_DEAD || victim->char_died(  ) )
   {
      projectile->extract(  );
      return rVICT_DIED;
   }

   if( wield )
      prof_bonus = weapon_prof_bonus_check( ch, wield, prof_gsn );
   else
      prof_bonus = 0;

   if( dt == TYPE_UNDEFINED )
   {
      dt = TYPE_HIT;
      if( wield && wield->item_type == ITEM_MISSILE_WEAPON )
         dt += wield->value[3];
   }

   thac0 = calc_thac0( ch, victim, dist );

   vic_ac = umax( -19, ( victim->GET_AC(  ) / 10 ) );

   /*
    * if you can't see what's coming... 
    */
   if( !victim->can_see_obj( projectile, false ) )
      vic_ac += 1;
   if( !ch->can_see( victim, false ) )
      vic_ac -= 4;

   /*
    * Weapon proficiency bonus 
    */
   vic_ac += prof_bonus;

   /*
    * The moment of excitement!
    */
   while( ( diceroll = number_bits( 5 ) ) >= 20 )
      ;

   if( diceroll == 0 || ( diceroll != 19 && diceroll < thac0 - vic_ac ) )
   {
      /*
       * Miss. 
       */
      if( prof_gsn != -1 )
         ch->learn_from_failure( prof_gsn );

      /*
       * Do something with the projectile 
       */
      if( number_percent(  ) < 50 )
         projectile->extract(  );
      else
      {
         if( projectile->carried_by )
            projectile->from_char(  );
         projectile->to_room( victim->in_room, victim );
      }
      damage( ch, victim, 0, dt );
      return rNONE;
   }

   /*
    * Hit.
    * Calc damage.
    */

   pchance = number_range( 1, 10 );

   switch ( pchance )
   {
      case 1:
      case 2:
      case 3: /* Hit in the arm */
         dam = number_range( projectile->value[1], projectile->value[2] ) + proj_bonus;
         break;

      case 4:
      case 5:
      case 6: /* Hit in the leg */
         dam = number_range( ( 2 * projectile->value[1] ), ( 2 * projectile->value[2] ) ) + proj_bonus;
         break;

      default:
      case 7:
      case 8:
      case 9:
      case 10:   /* Hit in the chest */
         dam = number_range( ( 3 * projectile->value[1] ), ( 3 * projectile->value[2] ) ) + proj_bonus;
         break;
   }

   /*
    * Bonuses.
    */
   dam += ch->GET_DAMROLL(  );

   if( prof_bonus )
      dam += prof_bonus / 4;

   /*
    * Calculate Damage Modifiers from Victim's Fighting Style
    */
   if( victim->position == POS_BERSERK )
      dam = 1.2 * dam;
   else if( victim->position == POS_AGGRESSIVE )
      dam = 1.1 * dam;
   else if( victim->position == POS_DEFENSIVE )
      dam = .85 * dam;
   else if( victim->position == POS_EVASIVE )
      dam = .8 * dam;

   if( !ch->isnpc(  ) && ch->pcdata->learned[gsn_enhanced_damage] > 0 && number_percent(  ) < ch->pcdata->learned[gsn_enhanced_damage] )
      dam += ( int )( dam * ch->LEARNED( gsn_enhanced_damage ) / 120 );
   else
      ch->learn_from_failure( gsn_enhanced_damage );

   if( !victim->IS_AWAKE(  ) )
      dam *= 2;

   if( dam <= 0 )
      dam = 1;

   plusris = 0;

   if( projectile->extra_flags.test( ITEM_MAGIC ) )
      dam = ris_damage( victim, dam, RIS_MAGIC );
   else
      dam = ris_damage( victim, dam, RIS_NONMAGIC );

   /*
    * Handle PLUS1 - PLUS6 ris bits vs. weapon hitroll   -Thoric
    */
   if( wield )
      plusris = wield->hitroll(  );

   /*
    * check for RIS_PLUSx - Thoric 
    */
   if( dam )
   {
      int x, res, imm, sus, mod;

      if( plusris )
         plusris = RIS_PLUS1 << UMIN( plusris, 7 );

      /*
       * initialize values to handle a zero plusris 
       */
      imm = res = -1;
      sus = 1;

      /*
       * find high ris 
       *//*
       * FIXME: Absorb handling needs to be included
       */
      for( x = RIS_PLUS1; x <= RIS_PLUS6; ++x )
      {
         if( victim->has_immune( x ) )
            imm = x;
         if( victim->has_resist( x ) )
            res = x;
         if( victim->has_suscep( x ) )
            sus = x;
      }
      mod = 10;
      if( imm >= plusris )
         mod -= 10;
      if( res >= plusris )
         mod -= 2;
      if( sus <= plusris )
         mod += 2;

      /*
       * check if immune 
       */
      if( mod <= 0 )
         dam = -1;
      if( mod != 10 )
         dam = ( dam * mod ) / 10;
   }

   /*
    * immune to damage 
    */
   if( dam == -1 )
   {
      if( dt >= 0 && dt < num_skills )
      {
         skill_type *skill = skill_table[dt];
         bool found = false;

         if( skill->imm_char && skill->imm_char[0] != '\0' )
         {
            act( AT_HIT, skill->imm_char, ch, nullptr, victim, TO_CHAR );
            found = true;
         }
         if( skill->imm_vict && skill->imm_vict[0] != '\0' )
         {
            act( AT_HITME, skill->imm_vict, ch, nullptr, victim, TO_VICT );
            found = true;
         }
         if( skill->imm_room && skill->imm_room[0] != '\0' )
         {
            act( AT_ACTION, skill->imm_room, ch, nullptr, victim, TO_NOTVICT );
            found = true;
         }
         if( found )
         {
            if( number_percent(  ) < 50 )
               projectile->extract(  );
            else
            {
               if( projectile->carried_by )
                  projectile->from_char(  );
               projectile->to_room( victim->in_room, victim );
            }
            return rNONE;
         }
      }
      dam = 0;
   }
   if( ( retcode = damage( ch, victim, dam, dt ) ) != rNONE )
   {
      if( projectile->value[5] == PROJ_STONE )
         projectile->extract(  );
      else
      {
         if( victim->char_died(  ) )
         {
            projectile->extract(  );
            return rVICT_DIED;
         }
         projectile->from_char(  );
         projectile->to_char( victim );
         projectile->extra_flags.set( ITEM_LODGED );

         switch ( pchance )
         {
            case 1:
            case 2:
            case 3: /* Hit in the arm */
               projectile->wear_flags.set( ITEM_LODGE_ARM );
               wear_obj( victim, projectile, true, get_wflag( "lodge_arm" ) );
               break;

            case 4:
            case 5:
            case 6: /* Hit in the leg */
               projectile->wear_flags.set( ITEM_LODGE_LEG );
               wear_obj( victim, projectile, true, get_wflag( "lodge_leg" ) );
               break;

            default:
            case 7:
            case 8:
            case 9:
            case 10:   /* Hit in the chest */
               projectile->wear_flags.set( ITEM_LODGE_RIB );
               wear_obj( victim, projectile, true, get_wflag( "lodge_rib" ) );
               break;
         }
      }
      return retcode;
   }
   if( ch->char_died(  ) )
   {
      projectile->extract(  );
      return rCHAR_DIED;
   }
   if( victim->char_died(  ) )
   {
      projectile->extract(  );
      return rVICT_DIED;
   }

   retcode = rNONE;
   if( dam == 0 )
   {
      if( number_percent(  ) < 50 )
         projectile->extract(  );
      else
      {
         if( projectile->carried_by )
            projectile->from_char(  );
         projectile->to_room( victim->in_room, victim );
      }
      return retcode;
   }

   /*
    * weapon spells -Thoric 
    */
   if( wield && !victim->has_immune( RIS_MAGIC ) && !victim->in_room->flags.test( ROOM_NO_MAGIC ) )
   {
      list < affect_data * >::iterator paf;

      for( paf = wield->pIndexData->affects.begin(  ); paf != wield->pIndexData->affects.end(  ); ++paf )
      {
         affect_data *af = *paf;

         if( af->location == APPLY_WEAPONSPELL && IS_VALID_SN( af->modifier ) && skill_table[af->modifier]->spell_fun )
            retcode = ( *skill_table[af->modifier]->spell_fun ) ( af->modifier, 7, ch, victim );
      }
      if( retcode != rNONE || ch->char_died(  ) || victim->char_died(  ) )
      {
         projectile->extract(  );
         return retcode;
      }

      for( paf = wield->affects.begin(  ); paf != wield->affects.end(  ); ++paf )
      {
         affect_data *af = *paf;

         if( af->location == APPLY_WEAPONSPELL && IS_VALID_SN( af->modifier ) && skill_table[af->modifier]->spell_fun )
            retcode = ( *skill_table[af->modifier]->spell_fun ) ( af->modifier, 7, ch, victim );
      }
      if( retcode != rNONE || ch->char_died(  ) || victim->char_died(  ) )
      {
         projectile->extract(  );
         return retcode;
      }
   }
   projectile->extract(  );
   return retcode;
}