コード例 #1
0
ファイル: handler.c プロジェクト: Lundessa/raven3
void affect_join(struct char_data *ch, struct affected_type *af,
		      bool add_dur, bool avg_dur, bool add_mod, bool avg_mod)
{
  struct affected_type *hjp, *next;
  bool found = FALSE;

  for (hjp = ch->affected; !found && hjp; hjp = next) {
    next = hjp->next;

    if ((hjp->spell == af->spell) && (hjp->location == af->location)) {
      if (add_dur)
	af->duration += hjp->duration;
      else if (avg_dur)
        af->duration = (af->duration+hjp->duration)/2;
      if (add_mod)
	af->modifier += hjp->modifier;
      else if (avg_mod)
        af->modifier = (af->modifier+hjp->modifier)/2;

      affect_remove(ch, hjp);
      affect_to_char(ch, af);
      found = TRUE;
    }
  }
  if (!found)
    affect_to_char(ch, af);
}
コード例 #2
0
ファイル: cls_shm.c プロジェクト: rayhe/stormgate
int spell_ethereal_wolf_howl( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA  *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
 
    if ( is_affected( victim, sn ) || is_affected( ch, sn ) )
    {
        return SKPELL_MISSED;
    }

    af.type      = sn;
    af.level     = level;
    af.duration  = level / 5;
    af.location  = APPLY_DAMROLL;
    af.modifier  = ( level / 5 ) * -1;
    af.bitvector = 0;
    affect_to_char( victim, &af );

    af.location  = APPLY_HITROLL;
    af.modifier  = ( level / 5 ) * -1;
    affect_to_char( victim, &af );

    af.location = APPLY_DAMROLL;
    af.modifier = level / 5;
    affect_to_char( ch, &af );

    af.location = APPLY_HITROLL;
    af.modifier	 = level / 5;
    affect_to_char( ch, &af );

    return SKPELL_NO_DAMAGE;
}
コード例 #3
0
ファイル: handler.c プロジェクト: okeuday/sillymud
void affect_join( struct char_data *ch, struct affected_type *af,
		 bool avg_dur, bool avg_mod )
{
  struct affected_type *hjp;
  bool found = FALSE;
  
  for (hjp = ch->affected; !found && hjp; hjp = hjp->next) {
    if ( hjp->type == af->type ) {
      
      af->duration += hjp->duration;
      if (avg_dur)
	af->duration /= 2;
      
      af->modifier += hjp->modifier;
      if (avg_mod)
	af->modifier /= 2;
      
      affect_remove(ch, hjp);
      affect_to_char(ch, af);
      found = TRUE;
    }
  }
  if (!found)
    affect_to_char(ch, af);
}
コード例 #4
0
ファイル: weather.c プロジェクト: jonm/SillyMUD
void sun_blind(struct char_data *ch) {
  struct affected_type af;

  if (get_max_level(ch) >= LOW_IMMORTAL)
    return;

  if (IS_AFFECTED2(ch, AFF2_SUN_BLIND))
    return;

  if (IS_AFFECTED(ch, AFF_BLIND))
    return;

  if (affected_by_spell(ch, SPELL_SUN_BLIND))
    affect_from_char(ch, SPELL_SUN_BLIND);

  send_to_char("Aaarrrggghh! The sun burns your eyes!\n\r", ch);

  af.type = SPELL_SUN_BLIND;
  af.location = APPLY_HITROLL;
  af.modifier = -4;
  af.duration = (number(1, 2) + (5 - get_max_level(ch) / 10));
  af.bitvector = 0;
  affect_to_char(ch, &af);

  af.location = APPLY_AC;
  af.modifier = +20;
  affect_to_char(ch, &af);

  af.modifier = 0;
  af.location = APPLY_BV2;
  af.bitvector = AFF2_SUN_BLIND;
  affect_to_char(ch, &af);
}
コード例 #5
0
ファイル: feeblemind.c プロジェクト: carriercomm/sillymud
void spell_feeblemind(byte level, struct char_data *ch,
		 struct char_data *victim, struct obj_data *obj)
{
  struct affected_type af;
  int t,i;

  if (!saves_spell(victim, SAVING_SPELL)) {

/* eld - I took the liberty of adding this little dandy..  In my opinion,  */
/*       this spell should not be accumulative.                            */

    if(affected_by_spell(victim, SPELL_FEEBLEMIND)) {
       send_to_char("They are already dumb enough as it is!\n\r", ch);
       return;
    } 

    send_to_char("You feel really really dumb\n\r", victim);

    af.type      = SPELL_FEEBLEMIND;
    af.duration  = 24;
    af.modifier  = -5;
    af.location  = APPLY_INT;
    af.bitvector = 0;
    affect_to_char(victim, &af);

    af.type      = SPELL_FEEBLEMIND;
    af.duration  = 24;
    af.modifier  = 70;
    af.location  = APPLY_SPELLFAIL;
    af.bitvector = 0;
    affect_to_char(victim, &af);

      /*
      last, but certainly not least
      */

    if (!victim->skills)
      return;

    t = number(1,100);

    while (1) {
      for (i=0;i<MAX_SKILLS;i++) {
	if (victim->skills[i].learned)
	  t--;
	if (t==0) {
	  victim->skills[i].learned = 0;
	  victim->skills[i].flags = 0;
	  break;
	}

/* eld - what happens if you get outside the for loop?  Yer screwed...  */
/*       this fixes it by giving the function something to do (return)  */

      }
      return;
    }
  }
}
コード例 #6
0
ファイル: Weave.cpp プロジェクト: justinabrahms/avendar
void Weave::UpdateAttunementsFor(CHAR_DATA & ch, int count)
{
    // Determine the modifier from the count
    static const int BaseValue = 15;
    int modifier(0);
  
    // Only allow non-zero modifiers if the skill is actually possessed
    if (get_skill(&ch, gsn_attunefount) > 0)
    {
        if (count > BaseValue)
        {
            // Anything over 15 founts is only worth a single point
            modifier = (count - BaseValue);
            count = BaseValue;
        }

        // This is a reduced formula using summations so it may not be clear what is going on:
        // Basically, the first fount is worth 2 * BaseValue, the next is worth 2 * (BaseValue - 1), the next 2 * (BaseValue - 2), and so on, until eventually they are worth exactly 1 each
        // So for BV = 15, the values are 30, 28, 26, 24, ..., 6, 4, 2, 1, 1, 1, ...
        modifier += (2 * ((BaseValue * count) - ((count * (count - 1)) / 2)));
    }

    // Compare the new modifier to the existing to see whether there is any change
    int prevModifier(0);
    AFFECT_DATA * paf(get_affect(&ch, gsn_attunefount));
    if (paf != NULL) prevModifier = paf->modifier;
    if (prevModifier == modifier)
        return;

    // Character needs a change; strip any existing effect and add the new one if appropriate
    affect_strip(&ch, gsn_attunefount);
    if (modifier == 0)
        send_to_char("You feel the last of your attunements leave you.\n", &ch);
    else
    {
        // Prepare the effect
        AFFECT_DATA af = {0};
        af.where    = TO_AFFECTS;
        af.type     = gsn_attunefount;
        af.duration = -1;
        af.modifier = modifier;
        af.location = APPLY_HIT;
        affect_to_char(&ch, &af);
    
        af.location = APPLY_MANA;
        affect_to_char(&ch, &af);

        // Adjust for gains (ignore losses)
        if (prevModifier < modifier)
        {
            ch.hit += (modifier - prevModifier);
            ch.mana += (modifier - prevModifier);
        }

        // Send an echo
        send_to_char("You feel the power of your attunements shift.\n", &ch);
    }
}
コード例 #7
0
ファイル: class_healer.c プロジェクト: blakepell/CrimsonSkies
/*
 * Allows a healer to boost the life force of a recipient (e.g. increase their
 * max health points and movement for a level's worth of ticks).  The modifier
 * (how much hp and move they receive) will be calculated by the healer's casting
 * level.  This cannot be cast on NPC's as a way to make them stronger.
 */
void spell_life_boost(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;
    int modifier = 0;

    // Not on NPC's
    if (IS_NPC(victim))
    {
        send_to_char("You failed.\r\n", ch);
        return;
    }

    if (is_affected(victim, sn))
    {
        if (victim == ch)
        {
            // Remove the affect so it can be re-added to yourself
            affect_strip(victim, sn);
        }
        else
        {
            act("$N is already affected by the increased vitality.", ch, NULL, victim, TO_CHAR);
            return;
        }
    }

    // Base is the players level
    modifier = ch->level;

    // If the player is casting it on themselves we'll give them a 12hp-13hp bonus at 51.  Healer's
    // aren't going to be huge player killers so why not.
    if (ch == victim)
    {
        modifier += ch->level / 4;
    }

    af.where = TO_AFFECTS;
    af.type = sn;
    af.level = level;
    af.duration = level;
    af.modifier = modifier;
    af.location = APPLY_HIT;
    af.bitvector = 0;
    affect_to_char(victim, &af);

    af.location = APPLY_MOVE;
    affect_to_char(victim, &af);

    act("$N has been vitalized.", victim, NULL, victim, TO_ROOM);
    send_to_char("You feel an increased vitality.\r\n", victim);

    return;

} // end spell_life_boost
コード例 #8
0
bool spell_causticblast(int sn, int level, CHAR_DATA * ch, void * vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dam(dice(level, 4));

    // Blast them
    act("$n unleashes a blast of hissing acid upon $N!", ch, NULL, victim, TO_NOTVICT);
    act("You unleash a blast of hissing acid upon $N!", ch, NULL, victim, TO_CHAR);
    act("$n unleashes a blast of hissing acid upon you!", ch, NULL, victim, TO_VICT);
    
    if (saves_spell(level, ch, victim, DAM_ACID))
    {
        damage_old(ch, victim, dam / 2, sn, DAM_ACID, true);
        return true;
    }

    damage_old(ch, victim, dam, sn, DAM_ACID, true);
    if (!IS_VALID(victim) || victim->in_room != ch->in_room)
        return true;

    act("The acid eats away at you, leaving painful, ugly scars!", victim, NULL, NULL, TO_CHAR);
    act("The acid eats away at $m, leaving painful, ugly scars!", victim, NULL, NULL, TO_ROOM);
    
    // Apply -charisma
    AFFECT_DATA af = {0};
    af.where    = TO_AFFECTS;
    af.type     = sn;
    af.level    = level;
    af.duration = level / 2;
    af.location = APPLY_CHR;
    af.modifier = -1;
    affect_to_char(victim, &af);

    // Apply burning
    for (AFFECT_DATA * paf(get_affect(victim, sn)); paf != NULL; paf = get_affect(victim, sn, paf))
    {
        if (paf->location == APPLY_NONE)
        {
            paf->duration = UMAX(2, paf->duration);
            paf->modifier = UMIN(100, paf->modifier + 1);
            return true;
        }
    }

    af.duration = 2;
    af.location = APPLY_NONE;
    af.modifier = 1;
    affect_to_char(victim, &af);
    return true;
}
コード例 #9
0
ファイル: magic.c プロジェクト: madvlad/doom-mud
/* affect_update: called from comm.c (causes spells to wear off) */
void affect_update(void)
{
  struct affected_type *af, *next;
  struct char_data *i;

  for (i = character_list; i; i = i->next) {
    for (af = i->affected; af; af = next) {
      next = af->next;
      if (af->duration >= 1)
        af->duration--;
      else if (af->duration == -1)	/* No action */
        af->duration = -1;	/* GODs only! unlimited */
      else {
        if ((af->type > 0) && (af->type <= MAX_SPELLS))
          if (!af->next || (af->next->type != af->type) || (af->next->duration > 0))
            if (spell_info[af->type].wear_off_msg)
              send_to_char(i, "%s\r\n", spell_info[af->type].wear_off_msg);
        affect_remove(i, af);
        /** Add Fatigue if coming down from berserk */
        if(af->type == SKILL_BERSERK){ //|| af->type == adrenaline shot){
          af->type = 1; //Banankick: not sure if this works.
          af->duration = 10;
          af->modifier = -10;
          af->location = APPLY_EVASION;        //APPLY_NONE?
          af->bitvector = AFF_FATIGUED;
          affect_to_char(i, &af);
        }
      }
    }
  }
}
コード例 #10
0
ファイル: class_healer.c プロジェクト: blakepell/CrimsonSkies
/*
 * A spell to help the healer resist some offensive magics against it.  Healer's don't
 * have many offensive weapons and thus are vulnerable characters, this should help
 * at least protect them a little more from spells.  This should be set to target
 * char_self so it can only be cast on the healer themselves.  We don't want to create
 * super chars with saves who make casters worthless.
 */
void spell_magic_resistance(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if (is_affected(victim, sn))
    {
        affect_strip(victim, sn);
    }

    af.where = TO_AFFECTS;
    af.type = sn;
    af.level = level;
    af.duration = level;
    af.modifier = (ch->level / 10) * -1;
    af.location = APPLY_SAVES;
    af.bitvector = 0;
    affect_to_char(victim, &af);

    act("$N has an enhanced resistance to magic.", victim, NULL, victim, TO_ROOM);
    send_to_char("You feel an enhanced resistance to magic.\r\n", victim);

    return;

} // end magic resistance
コード例 #11
0
ファイル: class_healer.c プロジェクト: blakepell/CrimsonSkies
/*
 * Sense affliction will allow the healer to see an (Affliction) flag on a player when
 * they do a 'look' in the room if a player is afflicted by something the healer can
 * cure.  If the healer looks at the person specifically they will see everything they
 * are afflicted with that they can cure specifically.  The healer can cast this on
 * themselves but not others.  This has a long duration and is not dispelable.  I
 * suppose this could also have just been a skill.
 */
void spell_sense_affliction(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if (is_affected(victim, sn))
    {
        // Remove the affect so it can be re-added to yourself
        affect_strip(victim, sn);
    }

    af.where = TO_AFFECTS;
    af.type = sn;
    af.level = level;
    af.duration = ch->level + (ch->level / 2);
    af.modifier = 0;
    af.location = APPLY_NONE;
    af.bitvector = 0;
    affect_to_char(victim, &af);

    send_to_char("Your senses for those afflicted are heightened.\r\n", victim);

    if (ch != victim)
    {
        act("$N's senses for those afflicted are heightened.", victim, NULL, victim, TO_ROOM);
    }

    return;

} // end spell_sense_affliction
コード例 #12
0
ファイル: mgc.c プロジェクト: kalendae/emlenmud-for-centos
void
renew_affect (CHAR_DATA * ch, AFFECT_DATA * aff)
{
  AFFECT_DATA *paf;
  AFFECT_DATA pasaf;
  bool foundd;
  foundd = FALSE;
  bzero (&pasaf, sizeof (pasaf));
  pasaf.type = aff->type;
  pasaf.duration = aff->duration;
  pasaf.location = aff->location;
  pasaf.modifier = aff->modifier;
  pasaf.bitvector = aff->bitvector;
  pasaf.bitvector2 = aff->bitvector2;
  for (paf = ch->affected; paf != NULL; paf = paf->next)
    {
      if (paf->type == aff->type && paf->location == aff->location)
	{
	  paf->duration = aff->duration;
	  foundd = TRUE;
	}
    }
  if (!foundd)
    affect_to_char (ch, &pasaf);
  return;
}
コード例 #13
0
ファイル: class_healer.c プロジェクト: blakepell/CrimsonSkies
/*
 * Enhanced recovery will allow the recipient to heal more on every tick.  Originally this
 * spell was written for another class (on 5/26/2000) but it fits better under a healer.
 */
void spell_enhanced_recovery(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if (is_affected(victim, sn))
    {
        if (victim == ch)
        {
            // Remove the affect so it can be re-added to yourself
            affect_strip(victim, sn);
        }
        else
        {
            act("$N is already blessed with enhanced recovery.", ch, NULL, victim, TO_CHAR);
            return;
        }
    }

    af.where = TO_AFFECTS;
    af.type = sn;
    af.level = level;
    af.duration = (ch->level / 2);
    af.modifier = 0;
    af.location = APPLY_NONE;
    af.bitvector = 0;
    affect_to_char(victim, &af);

    act("$N has been blessed with an enhanced recovery.", victim, NULL, victim, TO_ROOM);
    send_to_char("You feel blessed with a enhanced recovery.\r\n", victim);

} // end spell_enhanced_recovery
コード例 #14
0
ファイル: character.c プロジェクト: ryjen/muddled
int load_char_affects(Character *ch)
{
    char buf[400];
    sql_stmt *stmt;
    int total = 0;
    int len = sprintf(buf,
                      "select * from char_affect where characterId=%"
                      PRId64,
                      ch->id);

    if (sql_query(buf, len, &stmt) != SQL_OK)
    {
        log_data("could not prepare statement");
        return 0;
    }

    while (sql_step(stmt) != SQL_DONE)
    {
        int affId = sql_col_int(stmt, "affectId");
        Affect *aff = load_affect_by_id(affId);

        if (aff != 0)
        {
            aff->duration = sql_col_int(stmt, "duration");
            affect_to_char(ch, aff);
        }
        total++;
    }

    if (sql_finalize(stmt) != SQL_OK)
    {
        log_data("could not finalize statement");
    }
    return total;
}
コード例 #15
0
ファイル: magic4.c プロジェクト: bramblevine/adesa
bool spell_innerflame_master(int sn, int level, CHAR_DATA *ch, void *vo, OBJ_DATA *obj)
{
    AFFECT_DATA         af;

    if (   is_affected(ch, gsn_innerflame_novice)
        || is_affected(ch, gsn_innerflame_intermediate)
        || is_affected(ch, gsn_innerflame_advanced)
        || is_affected(ch, gsn_innerflame_expert)
        || is_affected(ch, gsn_innerflame_master))
        return FALSE;

    af.type = sn;
    af.duration = 15;
    af.location = 0;
    af.modifier = 0;
    af.bitvector = 0;
    af.save = TRUE;
    affect_to_char(ch, &af);

    act("You concentrate on your inner flame.", ch, NULL, NULL, TO_CHAR);
    act("$n concentrates on $s inner flame.", ch, NULL, NULL, TO_ROOM);

    return TRUE;

}
コード例 #16
0
ファイル: raceskill.c プロジェクト: bbailey/eosredux
void do_drowfire(CHAR_DATA * ch, char *argument)
{
	AFFECT_DATA af;
	CHAR_DATA *victim;

	if (ch->race != RACE_DROW) {
		send_to_char(AT_GREY, "Drowfire by a non-drow?\n\r", ch);
		return;
	}

	if (argument[0] != '\0') {
		if (!(victim = get_char_room(ch, argument))) {
			send_to_char(C_DEFAULT, "They aren't here.\n\r", ch);
			return;
		}
	} else {
		if (!(victim = ch->fighting)) {
			send_to_char(C_DEFAULT,
				     "You aren't fighting anyone.\n\r", ch);
			return;
		}
	}
	if (is_affected(victim, gsn_drowfire))
		return;

	WAIT_STATE(ch, skill_table[gsn_drowfire].beats);
	af.type = gsn_drowfire;
	af.level = ch->level;
	af.duration = ch->level / 10;
	af.location = APPLY_AC;
	af.modifier = 5 * ch->level;
	af.bitvector = 0;
	affect_to_char(victim, &af);
	af.location = APPLY_HITROLL;
	af.modifier = 0 - ch->level / 5;
	af.bitvector = 0;
	affect_to_char(victim, &af);

	send_to_char(AT_PINK, "You are surrounded by a purple outline.\n\r",
		     victim);
	act(AT_PINK, "$n is surrounded by a purple outline.", victim, NULL,
	    NULL, TO_ROOM);
	if (!victim->fighting)
		set_fighting(victim, ch);

	return;
}
コード例 #17
0
ファイル: act.obj2.c プロジェクト: MUDOmnibus/DikuMUD-Alfa
void do_taste(struct char_data *ch, char *argument, int cmd)
{
	struct affected_type af;
	char arg[MAX_STRING_LENGTH];
	char buf[MAX_STRING_LENGTH];
	struct obj_data *temp;

	one_argument(argument,arg);

	if(!(temp = get_obj_in_list_vis(ch,arg,ch->carrying)))
	{
		act("You can't find it!",FALSE,ch,0,0,TO_CHAR);
		return;
	}

	if(temp->obj_flags.type_flag==ITEM_DRINKCON)
	{
		do_sip(ch,argument,0);
		return;
	}

	if(!(temp->obj_flags.type_flag==ITEM_FOOD))
	{
		act("Taste that?!? Your stomach refuses!",FALSE,ch,0,0,TO_CHAR);
		return;
	}

	act("$n tastes the $o", FALSE, ch, temp, 0, TO_ROOM);
	act("You taste the $o", FALSE, ch, temp, 0, TO_CHAR);

	gain_condition(ch,FULL,1);

	if(GET_COND(ch,FULL)>20)
		act("You are full.",FALSE,ch,0,0,TO_CHAR);

	if(temp->obj_flags.value[3]&&!IS_AFFECTED(ch,AFF_POISON)) /* The shit was poisoned ! */
	{
		act("Ooups, it did not taste good at all!",FALSE,ch,0,0,TO_CHAR);

		af.type = SPELL_POISON;
		af.duration = 2;
		af.modifier = 0;
		af.location = APPLY_NONE;
		af.bitvector = AFF_POISON;
		affect_to_char(ch,&af);
	}

	temp->obj_flags.value[0]--;

	if(!temp->obj_flags.value[0])	/* Nothing left */
	{
		act("There is nothing left now.",FALSE,ch,0,0,TO_CHAR);
		extract_obj(temp);
	}

	return;

}
コード例 #18
0
ファイル: act_comm.c プロジェクト: zachflower/oasis-mud
void do_pray( CHAR_DATA * ch, char * argument ) {
  if ( !IS_GOOD( ch ) ) {
    send_to_char( AT_BLUE, "Thalador forgives some of your sins.\n\r", ch );
    ch->alignment += 10;
  } else if ( !IS_NPC( ch ) && ch->pcdata->learned[ gsn_prayer ] < number_percent() ) {
    send_to_char( AT_BLUE, "Thalador smiles upon you, and sends you a gold coin.\n\r", ch );
    ch->money.gold += 1;
  } else if ( !is_affected( ch, gsn_prayer ) ) {
    AFFECT_DATA af;

    af.duration  = ch->level / 3;
    af.level     = ch->level;
    af.type      = gsn_prayer;
    af.bitvector = 0;

    af.location = APPLY_HIT;
    af.modifier = number_range( ch->level, ch->level * 2 );
    affect_to_char( ch, &af );

    af.location = APPLY_MANA;
    af.modifier = number_range( ch->level / 2, ch->level );
    affect_to_char( ch, &af );

    af.location = APPLY_INT;
    af.modifier = ( ( ch->level - 1 ) / 50 ) + 1;
    affect_to_char( ch, &af );

    af.location = APPLY_DEX;
    affect_to_char( ch, &af );

    send_to_char( AT_BLUE, "Thalador places his blessing upon you.\n\r", ch );
    update_skpell( ch, gsn_prayer );
  } else {
    send_to_char( AT_BLUE, "Thalador frowns at your greed.\n\r", ch );
    ch->alignment -= 10;
  }

  send_to_char( AT_GREY, "You fall to the ground, unconscious.\n\r", ch );
  act( AT_GREY, "$n falls to the ground, unconscious.", ch, NULL, NULL, TO_ROOM );
  STUN_CHAR( ch, 4, STUN_COMMAND );
  return;
}
コード例 #19
0
ファイル: weather.c プロジェクト: jonm/SillyMUD
void remove_sun_blind(struct char_data *ch) {
  struct affected_type af;

  if (get_max_level(ch) >= LOW_IMMORTAL)
    return;

  send_to_char("Your vision begins to return.\n\r", ch);
  act("$n's vision begins to return.\n\r", TRUE, ch, 0, 0, TO_ROOM);
  affect_from_char(ch, SPELL_SUN_BLIND);

  af.type = SPELL_SUN_BLIND;
  af.location = APPLY_HITROLL;
  af.modifier = -2;
  af.duration = 1;
  af.bitvector = 0;
  affect_to_char(ch, &af);

  af.location = APPLY_AC;
  af.modifier = +10;
  affect_to_char(ch, &af);

}
コード例 #20
0
ファイル: swordtech.c プロジェクト: borlak/umgw
void swordtech(CHAR_DATA * ch, long bit)
{
	AFFECT_DATA af;

	if(!ch || IS_NPC(ch))
		return;

	af.type = gsn_swordtech;
	af.duration = 3 + ch->pcdata->stats[UNI_GEN];
	af.modifier = 0;
	af.location = 0;
	af.bitvector = bit;
	affect_to_char(ch, &af);
}
コード例 #21
0
bool spell_ordainsanctum(int sn, int level, CHAR_DATA * ch, void * vo, int target)
{
    // Sanity check
    if (ch->in_room == NULL)
    {
        bug("Ordain sanctum called from null room", 0);
        return false;
    }

    // Check for cooldown
    if (is_affected(ch, sn))
    {
        send_to_char("You are not yet ready to ordain this ground.\n", ch);
        return false;
    }

    // Check for effect already present
    if (room_is_affected(ch->in_room, sn))
    {
        send_to_char("This place has already been ordained as a sanctum.\n", ch);
        return false;
    }

    // Check for annointing oil
    OBJ_DATA * obj(lookup_obj_extra_flag(ch, ITEM_ANNOINTINGOIL));
    if (obj == NULL)
    {
        send_to_char("You cannot ordain this place without holy oil.\n", ch);
        return false;
    }

    // Ordain the room
    act("You murmur a soft chant, pouring out $p as you do so.", ch, obj, NULL, TO_CHAR);
    act("$n murmurs a soft chant, pouring out $p as $e does so.", ch, obj, NULL, TO_ROOM);
    act("As the last of the oil is poured out, you sense a certain protective aura fill this place.", ch, NULL, NULL, TO_ALL);

    AFFECT_DATA af = {0};
    af.where    = TO_ROOM;
    af.type     = sn;
    af.level    = level;
    af.duration = (level / 12);
    affect_to_room(ch->in_room, &af);

    // Apply a cooldown
    af.duration = 14;
    affect_to_char(ch, &af);

    return true;
}
コード例 #22
0
ファイル: handler.c プロジェクト: Calebros/aol
void affect_join(struct char_data * ch, struct affected_type * af,
		      bool add_dur, bool avg_dur, bool add_mod, bool avg_mod)
{
  struct affected_type *hjp;
  bool found = FALSE;

  for (hjp = ch->affected; !found && hjp; hjp = hjp->next) {

    if ((hjp->type == af->type) && (hjp->location == af->location)) {
      if (add_dur) {
	af->duration += hjp->duration;
      }

      if (avg_dur) {
	af->duration >>= 1;
      }

      if (add_mod) {
	af->modifier += hjp->modifier;
      }

      if (avg_mod) {
	af->modifier >>= 1;
      }

      affect_remove(ch, hjp, 0);
      affect_to_char(ch, af);
      found = TRUE;
    }
  }

  if (!found) {
    affect_to_char(ch, af);
  }

}
コード例 #23
0
ファイル: class_healer.c プロジェクト: blakepell/CrimsonSkies
/*
 * A healing spell that will return small bits of health over the period of a few ticks
 * outside of the normal tick cycle.  This will cost half as much as a heal (because it
 * can only be cast once and is spread out.  Players will get 10hp every half tick if
 * they are below their max health.
 */
void spell_vitalizing_presence(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if (is_affected(victim, sn))
    {
        if (victim == ch)
        {
            // Remove the affect so it can be re-added to yourself
            affect_strip(victim, sn);
        }
        else
        {
            act("$N is already affected by the vitalizing presence.", ch, NULL, victim, TO_CHAR);
            return;
        }
    }

    af.where = TO_AFFECTS;
    af.type = sn;
    af.level = level;

    // Lasts longer on yourself
    if (ch == victim)
    {
        af.duration = 10;
    }
    else
    {
        af.duration = 5;
    }

    af.modifier = 0;
    af.location = APPLY_NONE;
    af.bitvector = 0;
    affect_to_char(victim, &af);

    act("$N is vitalized with a healing presence.", victim, NULL, victim, TO_ROOM);
    send_to_char("You are vitalized with a healing presence.\r\n", victim);

    return;

} // end spell_vitalizing_presence
コード例 #24
0
void handle_waterwheel_crystal_destroyed(CHAR_DATA & ch, OBJ_DATA & obj)
{
    // Look for the effect
    AFFECT_DATA * paf(get_obj_affect(&obj, gsn_constructwaterwheel));
    if (paf == NULL)
        return;

    // Echoes
    act("As you destroy $p, a surge of energy rushes from it and into you!", &ch, &obj, NULL, TO_CHAR);
    act("As $n destroys $p, a flash of blue light shines out from it, focused on $m!", &ch, &obj, NULL, TO_ROOM);

    // Strip the effect from the char if present
    for (AFFECT_DATA * waf(get_affect(&ch, gsn_constructwaterwheel)); waf != NULL; waf = get_affect(&ch, gsn_constructwaterwheel, waf))
    {
        if (waf->location == APPLY_MANA)
        {
            affect_remove(&ch, waf);
            break;
        }
    }

    // Determine modifier
    int modifier(paf->duration);
    if (number_percent() <= get_skill(&ch, gsn_stonecraft))
        check_improve(&ch, NULL, gsn_stonecraft, true, 4);
    else
    {
        check_improve(&ch, NULL, gsn_stonecraft, false, 4);
        modifier /= 2;
    }

    // Grant the new effect
    AFFECT_DATA af = {0};
    af.where    = TO_AFFECTS;
    af.type     = gsn_constructwaterwheel;
    af.level    = paf->level;
    af.modifier = UMAX(1, modifier);
    af.duration = af.modifier;
    af.location = APPLY_MANA;
    affect_to_char(&ch, &af);
}
コード例 #25
0
/*
 * Add or enhance an affect.
 */
void affect_join( CHAR_DATA *ch, AFFECT_DATA *paf )
{
    AFFECT_DATA *paf_old;
    bool found;

    found = FALSE;
    for ( paf_old = ch->affected; paf_old != NULL; paf_old = paf_old->next )
    {
	if ( paf_old->type == paf->type && paf_old->flags == paf->flags )
	{
	    paf->strength = (paf->strength += paf_old->strength) / 2;
	    paf->duration += paf_old->duration;
	    paf->modifier += paf_old->modifier;
	    affect_remove( ch, paf_old );
	    break;
	}
    }

    affect_to_char( ch, paf );
    return;
}
コード例 #26
0
bool spell_hoarfrost(int sn, int level, CHAR_DATA * ch, void * vo, int target)
{
    // Sanity check
    if (ch->in_room == NULL || !ON_GROUND(ch))
    {
        send_to_char("There is no solid ground here to rime over.\n", ch);
        return false;
    }

    // Check for cooldown
    if (is_affected(ch, sn))
    {
        send_to_char("You are not prepared to conjure more hoarfrost yet.\n", ch);
        return false;
    }

    // Check for the room already having some
    if (room_is_affected(ch->in_room, sn))
    {
        send_to_char("This place is already coated in hoarfrost.\n", ch);
        return false;
    }

    act("You spin in a slow circle, chanting softly as a thin layer of ice coats the ground.", ch, NULL, NULL, TO_CHAR);
    act("$n spins in a slow circle, chanting softly as a thin layer of ice coats the ground.", ch, NULL, NULL, TO_ROOM);

    // Add the effect
    AFFECT_DATA af = {0};
    af.where    = TO_ROOM;
    af.type     = sn;
    af.level    = level;
    af.duration = (level / 10);
    affect_to_room(ch->in_room, &af);

    // Add a cooldown
    af.duration = 8;
    affect_to_char(ch, &af);

    return true;
}
コード例 #27
0
ファイル: Forge.cpp プロジェクト: justinabrahms/avendar
void Forge::CompleteWeapon(CHAR_DATA & ch, ForgeContext & context)
{
    // Determine the number of bonus points to spend
    bool forgeMaster(false);
    int bonusPoints(ch.level / 2);
    if (number_percent() <= get_skill(&ch, gsn_forgemaster)) 
    {
        check_improve(&ch, NULL, gsn_forgemaster, true, 4);
        forgeMaster = true; 
        bonusPoints += 10;
    }
    else
        check_improve(&ch, NULL, gsn_forgemaster, false, 4);

    if (ch.in_room != NULL && room_is_affected(ch.in_room, gsn_lavaforge)) bonusPoints += 20;
    if (context.named) bonusPoints += 60;
    bonusPoints -= context.flaws * 20;

    switch (Luck::Check(ch))
    {
        case Luck::Lucky: bonusPoints += 5; break;
        case Luck::Unlucky: bonusPoints -= 5; break;
        default: break;
    }

    bonusPoints = UMAX(0, bonusPoints);

    // Build the special odds ranges from the weapon and base objects
    std::vector<std::pair<unsigned int, const SpecialInfo *> > specials;
    unsigned int nextIndex(0);
    for (SpecialMap::const_iterator iter(Specials().begin()); iter != Specials().end(); ++iter)
    {
        // Make sure there are sufficient points for at least 1 level of this special
        if (bonusPoints < iter->second.cost)
            continue;

        // Calculate odds
        unsigned int oddsRange(CalculateOddsRange(iter->second, context.weaponInfo->weapon, context.materials));
        if (oddsRange == 0)
            continue;
        
        // Add in the range
        specials.push_back(std::make_pair(nextIndex, &iter->second));
        nextIndex += oddsRange;
    }

    // Now choose the special types, up to three
    std::vector<const SpecialInfo *> chosenSpecials;
    if (nextIndex > 0)
    {
        for (size_t i(0); i < 3; ++i)
        {
            // Choose an index at random and find the associated special
            unsigned int index(number_range(0, nextIndex - 1));
            for (size_t j(0); j + 1 < specials.size(); ++j)
            {
                if (specials[j].first <= index && specials[j + 1].first > index)
                {
                    // Found the matching special, now verify that it is acceptable in the face of other chosen ones
                    const SpecialInfo * chosenSpecial(specials[j].second);
                    for (size_t k(0); k < chosenSpecials.size(); ++k)
                    {
                        // No duplicates and no more than one uniqueclass
                        if (chosenSpecials[k] == chosenSpecial || (chosenSpecials[k]->uniqueClass && chosenSpecial->uniqueClass))
                        {
                            chosenSpecial = NULL;
                            break;
                        }
                    }

                    if (chosenSpecial != NULL)
                        chosenSpecials.push_back(chosenSpecial);

                    break;
                }
            }
        }
    }

    // Create the base object
    OBJ_DATA * obj(create_object(get_obj_index(OBJ_VNUM_FORGEWEAPON), 0));
    if (obj == NULL)
    {
        bug("Forge weapon failed due to bad obj creation", 0);
        send_to_char("An error has occurred, please contact the gods.\n", &ch);
        return;
    }

    // Fill out the basic info; use the first material as the object's material
    obj->level = ch.level;
    obj->weight = number_range(context.weaponInfo->minWeight, (context.weaponInfo->minWeight * 23) / 20);
    obj->weight = UMIN(obj->weight, context.weight);
    obj->size = context.weaponInfo->objSize;
    obj->cost = ((bonusPoints * bonusPoints) / 2) + number_range(0, 300);
    if (!context.materials.empty()) obj->material = context.materials[0];
    if (!context.weaponInfo->damverbs.empty()) 
        copy_string(obj->obj_str, context.weaponInfo->damverbs[number_range(0, context.weaponInfo->damverbs.size() - 1)].c_str());

    obj->value[0] = context.weaponInfo->type;
    obj->value[1] = 10 + (ch.level / 10) + context.weaponInfo->dammod + (context.named ? 1 : 0);
    obj->value[2] = 2;
    obj->value[3] = context.weaponInfo->damtype;
    if (context.weaponInfo->twohanded) SET_BIT(obj->value[4], WEAPON_TWO_HANDS);

    // Now choose from the selected specials at random until out of points or possible specials
    while (bonusPoints > 0 && !chosenSpecials.empty())
    {
        // Choose a special and add it in
        size_t index(number_range(0, chosenSpecials.size() - 1));
        chosenSpecials[index]->callback(*obj);
        bonusPoints -= UMAX(1, chosenSpecials[index]->cost);

        // Remove the special if too costly for the remaining points or only one allowed
        if (bonusPoints < chosenSpecials[index]->cost || !chosenSpecials[index]->multipleAllowed)
        {
            chosenSpecials[index] = chosenSpecials[chosenSpecials.size() - 1];
            chosenSpecials.pop_back();
        }
    }

    // Compensate for bad luck with increased damage
    if (context.named && bonusPoints >= 10)
        ++obj->value[1];

    // Choose an adjective from the set of common adjectives plus the weapon-specific adjectives
    WordList adjectives(Adjectives());
    for (size_t i(0); i < context.weaponInfo->adjectives.size(); ++i)
        adjectives.push_back(context.weaponInfo->adjectives[i]);

    std::string adjective;
    if (!adjectives.empty()) 
        adjective = adjectives[number_range(0, adjectives.size() - 1)];

    // Break down the material set to only unique materials
    std::set<int> materials;
    for (size_t i(0); i < context.materials.size(); ++i)
        materials.insert(context.materials[i]);

    std::string materialAdjective;
    switch (materials.size())
    {
        case 0: break;
        case 1: materialAdjective = material_table[context.materials[0]].name; break;
        case 2: 
        {
            std::set<int>::iterator iter(materials.begin());
            materialAdjective = material_table[*iter].name;
            materialAdjective += '-';
            ++iter;
            materialAdjective += material_table[*iter].name;
            break;
        }
        default:
            materialAdjective = material_table[context.materials[0]].name;
            materialAdjective += "-alloyed";
            break;
    }

    // Build the short desc
    std::ostringstream shortDesc;
    if (!adjective.empty()) shortDesc << adjective << ' ';
    if (!materialAdjective.empty()) shortDesc << materialAdjective << ' ';
    shortDesc << context.weaponInfo->name;

    std::string weaponShort(shortDesc.str());
    if (!weaponShort.empty())
        weaponShort = std::string(indefiniteArticleFor(weaponShort[0])) + ' ' + weaponShort;

    SetBasicDescs(*obj, weaponShort.c_str(), false);

    // Set up the exdesc
    std::ostringstream exdesc;
    switch (number_range(0, 2))
    {
        case 0: exdesc << "Forged"; break;
        case 1: exdesc << "Formed"; break;
        default: exdesc << "Wrought"; break;
    }
    exdesc << " from ";

    switch (materials.size())
    {
        case 0: exdesc << " pure metal"; break;
        case 1: exdesc << " pure " << material_table[context.materials[0]].name; break;
        case 2:
        {
            std::set<int>::iterator iter(materials.begin());
            exdesc << "an alloy of " << material_table[*iter].name << " and ";
            ++iter;
            exdesc << material_table[*iter].name;
            break;
        }
        default: exdesc << " a metal alloy"; break;
    }
    exdesc << ", this ";
    if (!adjective.empty()) exdesc << adjective << ' ';
    exdesc << context.weaponInfo->name;

    if (IS_OBJ_STAT(obj, ITEM_GLOW)) exdesc << " gleams brightly.";
    else if (IS_OBJ_STAT(obj, ITEM_DARK)) exdesc << " seems to drink the light into its dark surface.";
    else if (IS_OBJ_STAT(obj, ITEM_HUM)) exdesc << " hums faintly.";
    else if (IS_OBJ_STAT(obj, ITEM_NODESTROY)) exdesc << " seems nearly indestructible.";
    else if (context.named) exdesc << " radiates an aura of power.";
    else if (forgeMaster) exdesc << " has been masterfully crafted.";
    else exdesc << " has been well-crafted.";

    exdesc << ' ';
    switch (number_range(0, 5))
    {
        case 0: exdesc << "The bands of metal which comprise it have been folded over and over to toughen the final product."; break;
        case 1: exdesc << "Bands of metal flash-forged together serve to harden the weapon against wear."; break;
        case 2: exdesc << "Carved into the weapon's length are small straight-lined runes, etched with obvious care."; break;
        case 3: exdesc << "Folds of the metal have been beaten into the weapon's surface, reinforcing the craftsmanship."; break;
        case 4: exdesc << "Ornate filigree runs the length of the weapon, decorating it in gleaming metal."; break;
        default: exdesc << "The lines of the weapon are simple and unadorned, lending it a certain grim elegance."; break;
    }

    if (!context.weaponInfo->sentences.empty() && number_bits(1) == 0)
        exdesc << ' ' << context.weaponInfo->sentences[number_range(0, context.weaponInfo->sentences.size() - 1)];

    if (TraitCount(*obj, Trait_Parry) > 0)
        exdesc << " Forged with unusual precision, the balance of this piece lends itself well to parrying blows.";

    if (TraitCount(*obj, Trait_Casting) > 0)
        exdesc << " A sense of focus permeates this piece, as though it has been well-prepared for the channeling of mystical energies.";

    switch (context.flaws)
    {
        case 0: 
            switch (number_range(0, 3))
            {
                case 0: exdesc << " The work is flawless, bearing no sign of weakness."; break;
                case 1: exdesc << " Clearly well-fashioned, this " << context.weaponInfo->name << " has been made to stand the test of time."; break;
                case 2: exdesc << " No trace of imperfection mars the surface of this beautiful " << context.weaponInfo->name << '.'; break;
                default: exdesc << " There is no sign of seam or solder, as though the weapon was cast as a single, perfect unit."; break;
            }
            break;

        case 1:
            switch (number_range(0, 2))
            {
                case 0: exdesc << " A few minor imperfections mar the otherwise smooth surface of the " << context.weaponInfo->name << '.'; break;
                case 1: exdesc << " Though not immediately-visible, a couple of minor flaws are evident upon closer inspection."; break;
                default: exdesc << " Some dents remain from the original crafting, slightly weakening the metalwork."; break;
            }
            break;

        default:
            switch (number_range(0, 2))
            {
                case 0: exdesc << " Significant flaws are evident along the " << context.weaponInfo->name << "'s length."; break;
                default: exdesc << " Several seams show clearly on the weapon's surface, evidence of clumsy forgework."; break;
            }
            break;
    }

    // Apply the desc
    exdesc << '\n';
    EXTRA_DESCR_DATA * extraDesc(new_extra_descr());
    copy_string(extraDesc->keyword, obj->name);
    copy_string(extraDesc->description, exdesc.str().c_str());
    extraDesc->description = format_string(extraDesc->description);
    extraDesc->next     = obj->extra_descr;
    obj->extra_descr    = extraDesc;

    // Give the object to the char
    obj_to_char(obj, &ch);

    // Echoes (and charge max mana for the naming, if present)
    act("You quench the metalwork, now shaped into $p.", &ch, obj, NULL, TO_CHAR);
    act("$n quenches the metalwork, now shaped into $p.", &ch, obj, NULL, TO_ROOM);
    if (context.named)
    {
        act("You can feel the air about it charged with power drained from your very being, as the newly-forged weapon lies waiting to receive its true Name.", &ch, obj, NULL, TO_CHAR);
        ch.max_mana = UMAX(0, ch.max_mana - NamingManaCost);
        if (!IS_NPC(&ch))
            ch.pcdata->perm_mana = UMAX(0, ch.pcdata->perm_mana - NamingManaCost);

        ch.mana = UMIN(ch.mana, ch.max_mana);

        // Add an effect to the char to indicate he can name the object
        AFFECT_DATA af = {0};
        af.where    = TO_AFFECTS;
        af.type     = gsn_forgeweapon;
        af.location = APPLY_HIDE;
        af.duration = -1;
        af.point    = obj;
        af.level    = ch.level;
        affect_to_char(&ch, &af);
    }
}
コード例 #28
0
ファイル: Forge.cpp プロジェクト: justinabrahms/avendar
void Forge::CreateWeapon(CHAR_DATA & ch, const char * argument)
{
    // Perform basic skill check
    int skill(get_skill(&ch, gsn_forgeweapon));
    if (skill <= 0)
    {
        send_to_char("Huh?\n", &ch);
        return;
    }

    // Check for cooldown
    for (AFFECT_DATA * paf(get_affect(&ch, gsn_forgeweapon)); paf != NULL; paf = get_affect(&ch, gsn_forgeweapon, paf))
    {
        if (paf->point == NULL && paf->location == APPLY_NONE)
        {
            send_to_char("You are not ready for the trying process of forging another weapon just yet.\n", &ch);
            return;
        }
    }

    // Check for naming
    AFFECT_DATA * nameAff(FindNameEffect(ch));
    if (nameAff != NULL)
    {
        OBJ_DATA * nameObj(FindNameableObject(ch, *nameAff));
        if (nameObj != NULL)
        {
            act("You must first confer a true Name upon $p.", &ch, nameObj, NULL, TO_CHAR);
            return;
        }
        
        // No longer has the obj, so just clean up the effect and move on
        affect_remove(&ch, nameAff);
    }

    // Get the weapon type name
    char arg[MAX_INPUT_LENGTH];
    argument = one_argument(argument, arg);
    if (arg[0] == '\0')
    {
        send_to_char("Which type of weapon did you wish to forge?\n", &ch);
        return;
    }

    // Begin building the context, starting with the weapon type
    std::auto_ptr<ForgeContext> context(new ForgeContext);
    context->skill = skill;
    context->weaponInfo = LookupWeapon(arg);
    if (context->weaponInfo == NULL)
    {
        send_to_char("You do not know how to make weapons of that type.\n", &ch);
        return;
    }

    // Check for mana
    int manaCost(skill_table[gsn_forgeweapon].min_mana);
    if (ch.mana < manaCost)
    {
        send_to_char("You are too weary to forge a weapon right now.\n", &ch);
        return;
    }

    // Get the first object
    std::vector<OBJ_DATA*> baseObjects;
    if (!ObtainBaseObject(*context, baseObjects, ch, argument))
        return;

    // Check for an alloy
    argument = one_argument(argument, arg);
    if (arg[0] != '\0' && !str_prefix(arg, "alloy"))
    {
        if (!ObtainBaseObject(*context, baseObjects, ch, argument))
            return;

        argument = one_argument(argument, arg);
    }

    // Check for name
    if (arg[0] != '\0' && !str_prefix(arg, "name"))
    {
        // Verify max mana
        if (ch.max_mana < NamingManaCost)
        {
            send_to_char("You lack the will to speak a true Name.\n", &ch);
            return;
        }

        // Verify lava forge
        if (ch.in_room == NULL || !room_is_affected(ch.in_room, gsn_lavaforge))
        {
            send_to_char("You may only confer a true Name from the heat of the earth itself, at a lava forge.\n", &ch);
            return;
        }

        context->named = true;
        argument = one_argument(argument, arg);
    }

    // Check for superfluous arguments
    if (arg[0] != '\0')
    {
        send_to_char("Syntax: forgeweapon <type> <base_object> [alloy <base_object>] [name]\n", &ch);
        return;
    }

    // Check for sufficient weight
    if (context->weight < context->weaponInfo->minWeight)
    {
        std::ostringstream mess;
        mess << "Forging a " << context->weaponInfo->name << " requires more raw material than that!\n";
        send_to_char(mess.str().c_str(), &ch);
        return;
    }

    // Build object list to help with echoes
    std::ostringstream objMess;
    objMess << baseObjects[0]->short_descr;
    for (size_t i(1); (i + 1) < baseObjects.size(); ++i)
        objMess << ", " << baseObjects[i]->short_descr;

    if (baseObjects.size() > 1)
        objMess << " and " << baseObjects[baseObjects.size() - 1]->short_descr;

    std::string objList(objMess.str());

    // Perform initial echoes
    std::ostringstream mess;
    mess << "With a blast of heat and flame, you render down " << objList << " into a liquid mass of metal.";
    act(mess.str().c_str(), &ch, NULL, NULL, TO_CHAR);

    mess.str("");
    mess << "With a blast of heat and flame, $n renders down " << objList << " into a liquid mass of metal.";
    act(mess.str().c_str(), &ch, NULL, NULL, TO_ROOM);

    // Destroy the objects
    for (size_t i(0); i < baseObjects.size(); ++i)
        extract_obj(baseObjects[i]);

    // Set up the echo affect callbacks
    struct CallbackHandler
    {
        static bool HandleMove(CHAR_DATA * ch, ROOM_INDEX_DATA *, EchoAffect *, void * tag)
        {
            HandleCancel(ch, tag);
            return true;
        }

        static bool HandlePositionChange(CHAR_DATA * ch, int newPos, EchoAffect *, void * tag)
        {
            HandleCancel(ch, tag);
            return true;
        }

        static bool HandleCast(CHAR_DATA * ch, int, int, void *, int, EchoAffect *, void * tag)
        {
            HandleCancel(ch, tag);
            return true;
        }

        static bool CheckFailure(CHAR_DATA * ch, EchoAffect *, void * tag)
        {
            // Check for skill
            ForgeContext * context(static_cast<ForgeContext*>(tag));
            if (number_percent() <= context->skill)
            {    
                check_improve(ch, NULL, gsn_forgeweapon, true, 6);
                return false;
            }

            // Failed; increase the flaw count
            ++context->flaws;
            if (number_percent() <= context->flaws * 25)
            {
                // Fatal error
                act("You lose focus on your work, destroying it completely!", ch, NULL, NULL, TO_CHAR);
                act("$n loses focus on $s work, destroying it completely!", ch, NULL, NULL, TO_ROOM);
                check_improve(ch, NULL, gsn_forgeweapon, false, 6);
                delete context;
                return true;
            }

            // Non-fatal error
            act("You make a small error while folding the metal, introducing a slight flaw into the weapon.", ch, NULL, NULL, TO_CHAR);
            check_improve(ch, NULL, gsn_forgeweapon, false, 6);
            return false;
        }

        static bool Finish(CHAR_DATA * ch, EchoAffect *, void * tag)
        {
            std::auto_ptr<ForgeContext> context(static_cast<ForgeContext*>(tag));
            CompleteWeapon(*ch, *context);
            return false;
        }

        private:
            static void HandleCancel(CHAR_DATA * ch, void * tag)
            {
                std::auto_ptr<ForgeContext> context(static_cast<ForgeContext*>(tag));
                send_to_char("You abandon your efforts at the forge, letting the partially-worked metal run away to uselessness.\n", ch);
                act("$n abandons $s efforts at the forge, allowing the partially-worked metal to run away uselessly.", ch, NULL, NULL, TO_ROOM);
            }
    };

    // Prepare the echoAffect
    EchoAffect * echoAff(new EchoAffect(1));
    echoAff->SetPositionCallback(&CallbackHandler::HandlePositionChange);
    echoAff->SetMoveCallback(&CallbackHandler::HandleMove);
    echoAff->SetCastCallback(&CallbackHandler::HandleCast);

    // Add in lines
    echoAff->AddLine(&CallbackHandler::CheckFailure,
                    "Working the mass carefully, you begin to shape the metal.",
                    "Working the mass carefully, $n begins to shape the metal.");

    mess.str("");
    mess << "As you fold the metal over itself time and again, it starts to take on the distinctive shape of a ";
    mess << context->weaponInfo->name << ".";

    std::ostringstream omess;
    omess << "As $n folds the metal over itself time and again, it starts to take on the distinctive shape of a ";
    omess << context->weaponInfo->name << ".";

    echoAff->AddLine(&CallbackHandler::CheckFailure, mess.str().c_str(), omess.str().c_str());
    echoAff->AddLine(&CallbackHandler::CheckFailure,
                    "Molding the weapon with magic and skill, you bring your work near completion.",
                    "Molding the weapon with magic and skill, $n brings $s work near completion.");

    echoAff->AddLine(&CallbackHandler::Finish, "");

    // Finish applying the effect
    echoAff->SetTag(context.release());
    EchoAffect::ApplyToChar(&ch, echoAff);

    // Apply a cooldown
    AFFECT_DATA af = {0};
    af.where    = TO_AFFECTS;
    af.type     = gsn_forgeweapon;
    af.location = APPLY_NONE;
    af.duration = 60;
    af.level    = ch.level;
    affect_to_char(&ch, &af);

    // Charge mana and lag
    expend_mana(&ch, manaCost);
    WAIT_STATE(&ch, skill_table[gsn_forgeweapon].beats);
}
コード例 #29
0
ファイル: pipes.c プロジェクト: KillerMud/Source
void do_pipe ( CHAR_DATA *ch, char *argument )
{
	OBJ_DATA * pObj;
	OBJ_DATA * qObj;
	char *pipe_name;
	char pipe_name_2[MAX_INPUT_LENGTH];
	int amount, range, weed_amount, weed_type, dex, wis, con;
	AFFECT_DATA *old_smoke, *old_poison;
	AFFECT_DATA new_smoke, poison;
	int dur = 1, old_dur = 0, old_level = 0, level = 1;

	char buf[ MAX_INPUT_LENGTH ];

	char arg1[ MAX_INPUT_LENGTH ];
	char arg2[ MAX_INPUT_LENGTH ];
	char arg3[ MAX_INPUT_LENGTH ];
	char arg4[ MAX_INPUT_LENGTH ];

	// mobom dziêkujemy bez komunikatu
	if ( IS_NPC( ch ) )
	{
		return ;
	}

    // w czasie walki dziêkujemy z komunikatem
    if ( ch->position == POS_FIGHTING || ch->fighting != NULL )
	{
		send_to_char( "Lepiej skup siê na walce.\n\r", ch );
		return;
    }

	argument = one_argument( argument, arg1 );
	argument = one_argument( argument, arg2 );
	argument = one_argument( argument, arg3 );
	argument = one_argument( argument, arg4 );

	pObj = get_obj_carry( ch, arg2, ch );

	if ( arg1[ 0 ] == '\0' )
	{
		send_to_char( "Co takiego chcesz zrobiæ z fajk±?\n\r", ch );
		send_to_char( "{R[PORADA]:{y 'Je¿eli nie wiesz, co mo¿esz, wpisz {Rhelp pipe{x / {Cpomoc fajka{x.{Y'{x\n\r", ch );
		return;
	}

	if ( !str_prefix( arg1, "smoke" ) || !str_prefix( arg1, "pal" ))
	{
		if ( arg2[ 0 ] == '\0' )
		{
			send_to_char( "Paliæ co?\n\r", ch );
			return ;
		}

		// je¿eli obiekt nieistnieje w inventory, to mo¿e kto¶ co¶ takiego trzyma

		if ( pObj == NULL ) pObj = get_eq_char( ch, WEAR_HOLD );

		if ( pObj == NULL )
		{
			send_to_char( "Potrzebujesz fajki ¿eby paliæ ziele fajkowe.\n\r", ch );
			return ;
		}

		/*if ( ( pObj = get_obj_carry( ch, arg2, ch ) ) == NULL )
		{
			send_to_char( "Potrzebujesz fajki ¿eby paliæ ziele fajkowe.\n\r", ch );
			return ;
		}*/

		if ( pObj->item_type != ITEM_PIPE )
		{
			send_to_char( "Potrzebujesz fajki ¿eby paliæ ziele fajkowe.\n\r", ch );
			return ;
		}

		/* Gdy fajka jest pusta... */
		if ( pObj->value[ 1 ] <= 0 )
		{
			act( "W $j nie ma niczego, co móg³by¶ paliæ! Jest pusta.", ch, pObj, NULL, TO_CHAR );
			act( "$n spogl±da z dziwnym smutkiem na $h.", ch, pObj, NULL, TO_ROOM );
			return ;
		}

		/* Gdy fajka jest zgaszona*/
		if ( pObj->value[ 0 ] == 0 )
		{
			act( "Przecie¿ $p jest zgaszona!", ch, pObj, NULL, TO_CHAR );
			return ;
		}

		/* Flaga informujaca o tym, ze gracz sobie pociagnal dymka... */
		if ( !EXT_IS_SET( ch->act, PLR_SMOKED ) )
			EXT_SET_BIT( ch->act, PLR_SMOKED );

		if ( is_affected( ch, gsn_on_smoke ) )
		{
			old_smoke = affect_find( ch->affected, gsn_on_smoke );
			old_dur = old_smoke->duration;
			old_level = old_smoke->level;
			affect_strip( ch, gsn_on_smoke );
		}

		level = weed_table[ pObj->value[2] ].weed_affect[0];

		dur += old_dur;
		level += old_level;

		new_smoke.where = TO_AFFECTS;
		new_smoke.type = gsn_on_smoke;
		new_smoke.level = level;
		new_smoke.duration = UMIN( dur, number_range( 5, 7 ) );
		new_smoke.rt_duration = 0;
		new_smoke.location = APPLY_NONE;
		new_smoke.modifier = 0;
		new_smoke.bitvector = &AFF_NONE;

		if ( level > number_range( 5, 7 ) && weed_table[ pObj->value[2] ].weed_affect[0] && number_percent() < weed_table[ pObj->value[2] ].weed_affect[1] )
		{
			send_to_char( "\n\rZaczynasz czuæ siê jako¶ dziwnie. Przed oczyma zaczynaj± lataæ ci kolorowe plamki.\n\r", ch );
			act( "\n\r$n zaczyna wygl±dajaæ jako¶ dziwnie blado.", ch, pObj, NULL, TO_ROOM );
			if ( dice( 1, 2 ) == 1 )
				new_smoke.bitvector = &AFF_HALLUCINATIONS_NEGATIVE;
			else
				new_smoke.bitvector = &AFF_HALLUCINATIONS_POSITIVE;
		}
		new_smoke.visible = FALSE;
		affect_to_char( ch, &new_smoke, NULL, FALSE );

		if ( number_percent() < weed_table[ pObj->value[2] ].weed_affect[2] )
		{
			if( is_affected(ch,gsn_poison ))
			{
				old_poison = affect_find( ch->affected, gsn_poison );
				old_poison->duration += stat_throw(ch,STAT_CON) ? number_range(2,4) : number_range(4,8);
				if( old_poison->level < UMIN( weed_table[ pObj->value[2] ].weed_affect[0], 3) )
					old_poison->level = UMIN( weed_table[ pObj->value[2] ].weed_affect[0], 3);
				act( "$n jeszcze bardziej zielenieje na twarzy.", ch, pObj, NULL, TO_ROOM );
				send_to_char( "Czujesz siê jeszcze gorzej.\n\r", ch );
			}
			else
			{
				poison.where = TO_AFFECTS;
				poison.type = gsn_poison;
				poison.level = UMIN( weed_table[ pObj->value[2] ].weed_affect[0], 3);
				poison.duration = stat_throw(ch,STAT_CON) ? number_range(2,4) : number_range(4,8);
				poison.rt_duration = 0;
				poison.location = APPLY_NONE;
				poison.modifier = 0;
				poison.bitvector = &AFF_NONE;
				poison.visible = FALSE;
				affect_to_char( ch, &poison, NULL, FALSE );
				send_to_char( "Momentalnie zaczynasz czuæ siê jako¶ niedobrze. Bardzo niedobrze.\n\r", ch );
				act( "$n widocznie zielenieje na twarzy.", ch, pObj, NULL, TO_ROOM );
			}
		}

		/* Troche losowosci */
		range = number_range( 1, 9 );
		switch ( range )
		{
			case 1:
				act( "$n zaci±ga siê g³êboko $j.", ch, pObj, NULL, TO_ROOM );
				act( "Zaci±gasz siê g³êboko $j.", ch, pObj, NULL, TO_CHAR );
				break;
			case 2:
				act( "$n pyka sobie $h przez chwilê.", ch, pObj, NULL, TO_ROOM );
				act( "Pykasz sobie $h przez chwilê.", ch, pObj, NULL, TO_CHAR );
				break;
			case 3:
				act( "$n wci±ga gwa³townie dym z $f.", ch, pObj, NULL, TO_ROOM );
				act( "Wci±gasz gwa³townie dym z $f.", ch, pObj, NULL, TO_CHAR );
				break;
			case 4:
				act( "$n zaci±ga siê delikatnie $j.", ch, pObj, NULL, TO_ROOM );
				act( "Zaci±gasz siê delikatnie $j.", ch, pObj, NULL, TO_CHAR );
				break;
			case 5:
				act( "Widzisz jak $n zaci±ga siê lekko $j.", ch, pObj, NULL, TO_ROOM );
				act( "Zaci±gasz siê lekko $j.", ch, pObj, NULL, TO_CHAR );
				break;
			case 6:
				act( "Dostrzegasz, jak $n z wpraw± zaci±ga siê dymkiem z $f.", ch, pObj, NULL, TO_ROOM );
				act( "Z wielk± wpraw± zaci±gasz siê dymkiem z $f.", ch, pObj, NULL, TO_CHAR );
				break;
			case 7:
				act( "$n jakby od niechcenia pali przez chwilê swoj± $h.", ch, pObj, NULL, TO_ROOM );
				act( "Przez chwilkê machinalnie palisz sobie swoj± $h.", ch, pObj, NULL, TO_CHAR );
				break;
			case 8:
				act( "$n z u¶miechem kurzy sobie $h.", ch, pObj, NULL, TO_ROOM );
				act( "Kurzysz sobiê $h, u¶miechaj±c siê przy tym b³ogo.", ch, pObj, NULL, TO_CHAR );
				break;
			default:
				act( "$n pali sobie przez chwilkê $h.", ch, pObj, NULL, TO_ROOM );
				act( "Palisz sobie przez chwilkê $h.", ch, pObj, NULL, TO_CHAR );
				break;
		}

		amount = number_range( 1, 3 ); // moze sie palic szybciej, lub wolniej (o 1, 2 lub o 3)
		if ( pObj->value[ 0 ] == 1 )     // sprawdzamy czy fajeczka jest zapalona
		{
			pObj->value[ 1 ] -= amount; // wypalamy zawartosc fajeczki
			//pObj->short_descr = capitalize(pObj->short_descr );
			amount = number_range( 1, 7 );
			switch ( amount )
			{
				case 1:
					act( "Nad $j trzyman± przez $z unosi siê w±ska stru¿ka dymu.", ch, pObj, NULL, TO_ROOM );
					act( "Nad $j unosi siê w±ska stru¿ka dymu.", ch, pObj, NULL, TO_CHAR );
					break;
				case 2:
					act( "Nad $j $z unosz± siê ma³e, ciemne chmurki dymu.", ch, pObj, NULL, TO_ROOM );
					act( "Nad $j unosz± siê ma³e, ciemne chmurki dymu.", ch, pObj, NULL, TO_CHAR );
					break;
				case 3:
					act( "Widzisz jak w $f $z tl± siê ma³e, jasne iskierki.", ch, pObj, NULL, TO_ROOM );
					act( "Widzisz kilka ma³ych, jasnych iskierek tl±cych siê w $k.", ch, pObj, NULL, TO_CHAR );
					break;
				case 4:
					act( "Dostrzegasz, ¿e nad $f trzyman± przez $z unosi siê gêsta smuga dymu.", ch, pObj, NULL, TO_ROOM );
					act( "Dosrzegasz unosz±c± siê nad $f gêst± smugê dymu.", ch, pObj, NULL, TO_CHAR );
					break;
				case 5:
					act( "S³yszysz jak zawarto¶æ $f $z lekko syczy tl±c siê.", ch, pObj, NULL, TO_ROOM );
					act( "S³yszysz jak zawarto¶æ $f lekko syczy tl±c siê.", ch, pObj, NULL, TO_CHAR );
					break;
				case 6:
					act( "Czujesz delikatny aromat jakoby zio³owego dymu, bij±cy od $z i jego $f.", ch, pObj, NULL, TO_ROOM );
					act( "Czujesz bij±cy od $f lekki, jakby zio³owy aromat.", ch, pObj, NULL, TO_CHAR );
					break;
				default:
					act( "Zawarto¶æ $f nale¿±cej do $z tli siê lekko.", ch, pObj, NULL, TO_ROOM );
					act( "Zawarto¶æ $f tli siê lekko.", ch, pObj, NULL, TO_CHAR );
					break;
			}

			if ( pObj->value[ 1 ] <= 0 )
			{
				act( "Ostatnie, tl±ce siê iskierki gasn±, kiedy wypali³a siê ca³a zawarto¶æ $f.", ch, pObj, NULL, TO_CHAR );
				act( "Widzisz jak $p $z ga¶nie z lekkim sykiem.", ch, pObj, NULL, TO_ROOM );
				pObj->value[ 0 ] = 0;
				pObj->value[ 1 ] = 0;
				pObj->value [ 2 ] = 0;
			}
		}
		return ;
	}


	if ( !str_prefix( arg1, "exhale" ) || !str_prefix( arg1, "wydech" ))
	{
		// Potrzebne staty do testow na 'triki'...
		dex = get_curr_stat_deprecated(ch,STAT_DEX);
		con = get_curr_stat_deprecated(ch,STAT_CON);
		wis = get_curr_stat_deprecated(ch,STAT_WIS);

		/* Zeby "wydychac" flaga palenia musi byc nalozona na gracza - sprawdzanie */
		if ( !EXT_IS_SET( ch->act, PLR_SMOKED ) )
		{
			send_to_char( "Jak chcesz to zrobiæ? Najpierw musisz zaci±gn±æ siê dymem!\n\r", ch );
			return ;
		}

		/* Pomocy!
		if ( !str_prefix( arg2, "help" ) || !str_prefix( arg2, "pomoc" ))
		{
			act( "{R[PORADA]:{x\n\r", ch, NULL, NULL, TO_CHAR );
			act( "{YZanim bêdziesz <&móg³/mog³a/mog³o> wydychaæ dym musisz paliæ fajkê.{x", ch, NULL, NULL, TO_CHAR );
			act( "{YPo tym jak skoñczysz rozkoszowaæ siê bogatym smakiem ziela fajkowego...{x", ch, NULL, NULL, TO_CHAR );
			act( "{YMo¿esz wydychaæ tytoniowy dym na ró¿ne sposoby, ¿eby uatrakcyjniæ palenie.{x", ch, NULL, NULL, TO_CHAR );
			act( "{YSpróbuj tych oto typów wydechu, aby zadziwiæ znajomych:{x \n\r", ch, NULL, NULL, TO_CHAR );
			act( "Angielskie komendy: RINGS, LINES, SPHERE, WEB, PHOENIX, HORNS, NAME", ch, NULL, NULL, TO_CHAR );
			act( "Polskie komendy: KO£A, LINIE, KULA, SIEÆ, FENIKS, ROGI, IMIÊ\n\r", ch, NULL, NULL, TO_CHAR );
			act( "\n\r{YSk³adnia angielska: {Gpipe exhale <nazwa figury>{x.", ch, NULL, NULL, TO_CHAR );
			act( "{YSk³adnia polska: {Gfajka wydech <nazwa figury>{x.\n\r", ch, NULL, NULL, TO_CHAR );
			return ;
		}*/

		if ( arg2[ 0 ] == '\0' )
		{
			switch ( number_range ( 1, 5 ) )
			{
				case 1:
					act( "$n wydycha ustami ob³ok bladego, szarego dymu.", ch, NULL, NULL, TO_ROOM );
					act( "Wydychasz ustami ob³ok szarego, bladego dymu.", ch, NULL, NULL, TO_CHAR );
					EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
					return ;
				case 2:
					act( "$n wydycha nosem ob³ok bladego, szarego dymu.", ch, NULL, NULL, TO_ROOM );
					act( "Wydychasz nosem ob³ok szarego, bladego dymu.", ch, NULL, NULL, TO_CHAR );
					EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
					return ;
				case 3:
					act( "$n spokojnie wydycha ustami ob³ok bladego, szarego dymu.", ch, NULL, NULL, TO_ROOM );
					act( "Spokojnie wydychasz ustami ob³ok szarego, bladego dymu.", ch, NULL, NULL, TO_CHAR );
					EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
					return ;
				case 4:
					act( "$n spokojnie wydycha nosem ob³ok bladego, szarego dymu.", ch, NULL, NULL, TO_ROOM );
					act( "Spokojnie wydychasz nosem ob³ok szarego, bladego dymu.", ch, NULL, NULL, TO_CHAR );
					EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
					return ;
				default:
					act( "$n wydycha ob³ok bladego, szarego dymu.", ch, NULL, NULL, TO_ROOM );
					act( "Wydychasz ob³ok szarego, bladego dymu.", ch, NULL, NULL, TO_CHAR );
					EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
					return ;
			}
		}
		else if ( !str_prefix( arg2, "ko³a" ) || !str_prefix( arg2, "rings" ) )
		{
			if ( dice( 2, dex - 10 ) >= 4 && dice( 2, con - 6 ) > 6 )
			{
				act( "$n niespodziewanie wypuszcza z ust kilka du¿ych, zadziwiaj±co okr±g³ych kó³ z dymu, które uk³adaj± siê w ¶mieszny tunel zawieszony w powietrzu!", ch, NULL, NULL, TO_ROOM );
				act( "Wypuszczasz z ust kilka du¿ych, zadziwiaj±co okr±g³ych kó³ z dymu, które uk³adaj± siê w ¶mieszny tunel zawieszony w powietrzu!", ch, NULL, NULL, TO_CHAR );
				EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
				return ;
			}
			else
			{
				switch ( number_range ( 1, 4 ) )
				{
					case 1:
						act( "$n nagle robi dziwn± minê, po czym momentalnie dostaje ataku kaszlu.", ch, pObj, NULL, TO_ROOM );
						act( "Próbujesz zrobiæ sztuczkê, jednak w ostatniej chwili dym zacz±³ gry¼æ ciê w gar³o i <&dosta³e¶/dosta³a¶/dosta³o¶> ataku kaszlu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 2:
						act( "Widzisz jak $n koncentruje siê przez chwilkê, aby po chwili wypu¶ciæ z ust niekszta³tn± chmurê dymu.", ch, pObj, NULL, TO_ROOM );
						act( "Koncentrujesz siê przez chwilkê, chc±c wypu¶ciæ z ust chmurê dymu w kszta³cie ko³a, jednak nie udaje ci siê to.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 3:
						act( "$n nagle zielenieje na twarzy, a z jego nosa zaczynaj± wylatywaæ szare stru¿ki dymu.", ch, pObj, NULL, TO_ROOM );
						act( "W ostatniej chwili przygotowañ do zrobienia sztuczki krztusisz siê i bezwiednie wypuszczasz dym nosem.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					default:
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						act( "$n próbuje zrobiæ jak±¶ sztuczkê z wypuszczeniem z ust dymu, jednak udaje mu siê jedynie uformowaæ dym w bezkszta³tn± chmurê.", ch, pObj, NULL, TO_ROOM );
						act( "Starasz siê wypu¶ciæ z ust kilka kszta³tnych kó³, jednak nie udaje ci siê, a dym przybiera kszta³t nieforemnej chmury.", ch, pObj, NULL, TO_CHAR );
						break;
				}
			}
		}
		else if ( !str_prefix( arg2, "linie" ) || !str_prefix( arg2, "lines" ))
		{
			if ( dice( 2, dex - 10 ) > 5 && dice( 2, con - 8 ) >= 5 )
			{
				act( "$n wydycha d³ug± smugê dymu w kszta³cie piêknej, prostej linii, zdaj±c± siê pi±æ w kierunku nieba!", ch, NULL, NULL, TO_ROOM );
				act( "Wydychasz d³ug± smugê dymu w kszta³cie piêknej, prostej linii, zdaj±c± siê pi±æ w kierunku nieba!", ch, NULL, NULL, TO_CHAR );
				EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
				return ;
			}
			else
			{
				switch ( number_range ( 1, 5 ) )
				{
					case 1:
						act( "$n nagle robi dziwn± minê, po czym momentalnie dostaje ataku kaszlu.", ch, pObj, NULL, TO_ROOM );
						act( "Próbujesz zrobiæ sztuczkê, jednak w ostatniej chwili dym zacz±³ gry¼æ ciê w gar³o i <&dosta³e¶/dosta³a¶/dosta³o¶> ataku kaszlu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 2:
						act( "Widzisz jak $n koncentruje siê przez chwilkê, aby po chwili wypu¶ciæ z ust niekszta³tn± chmurê dymu.", ch, pObj, NULL, TO_ROOM );
						act( "Koncentrujesz siê przez chwilkê, chc±c wypu¶ciæ z ust chmurê dymu w kszta³cie linii, jednak nie udaje ci siê to.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 3:
						act( "$n nagle zielenieje na twarzy, a z jego nosa zaczynaj± wylatywaæ szare stru¿ki dymu.", ch, pObj, NULL, TO_ROOM );
						act( "W ostatniej chwili przygotowañ do zrobienia sztuczki krztusisz siê i bezwiednie wypuszczasz dym nosem.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 4:
						act( "$n z gracj± zaczyna wypuszczaæ z ust kilka chmurek dymu, które niespodziewanie szybko rozp³ywaj± siê w powietrzu.", ch, pObj, NULL, TO_ROOM );
						act( "W skupieniu wypuszczasz z ust kilka chmurek dymu, te jednak rozp³ywaj± siê szybko w powietrzu zanim zd±zy³y siê uformowaæ w jaki¶ kszta³t.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					default:
						act( "$n próbuje zrobiæ jak±¶ sztuczkê z wypuszczeniem z ust dymu, jednak udaje mu siê jedynie uformowaæ dym w bezkszta³tn± chmurê.", ch, pObj, NULL, TO_ROOM );
						act( "Starasz siê wypu¶ciæ z ust prost± liniê dymu, jednak nie udaje ci siê, a dym przybiera kszta³t nieforemnej chmury.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
				}
			}
		}
		else if ( !str_prefix( arg2, "kula" ) || !str_prefix( arg2, "sphere" ))
		{
			if ( dice( 2, dex - 5 ) >= 7 && dice( 3, con - 2 ) > 15 )
			{
				act( "$n wypuszcza z ust jedn±, niesamowicie okr±g³a, chmurê dymu w kszta³cie idealnej kuli!", ch, NULL, NULL, TO_ROOM );
				act( "Wypuszczasz z ust du¿±, niesamowicie okr±g³±, chmurê dymu w kszta³cie idealnej kuli!", ch, NULL, NULL, TO_CHAR );
				EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
				return ;
			}
			else
			{
				switch ( number_range ( 1, 5 ) )
				{
					case 1:
						act( "$n nagle robi dziwn± minê, po czym momentalnie dostaje ataku kaszlu.", ch, pObj, NULL, TO_ROOM );
						act( "Próbujesz zrobiæ sztuczkê, jednak w ostatniej chwili dym zacz±³ gry¼æ ciê w gar³o i <&dosta³e¶/dosta³a¶/dosta³o¶> ataku kaszlu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 2:
						act( "Widzisz jak $n koncentruje siê przez chwilkê, aby po chwili wypu¶ciæ z ust niekszta³tn± chmurê dymu.", ch, pObj, NULL, TO_ROOM );
						act( "Koncentrujesz siê przez chwilkê, chc±c wypu¶ciæ z ust chmurê dymu w kszta³cie kuli, jednak nie udaje ci siê to.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 3:
						act( "$n nagle zielenieje na twarzy, a z jego nosa zaczynaj± wylatywaæ szare stru¿ki dymu.", ch, pObj, NULL, TO_ROOM );
						act( "W ostatniej chwili przygotowañ do zrobienia sztuczki krztusisz siê i bezwiednie wypuszczasz dym nosem.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 4:
						act( "$n nagle zaczyna kaszlaæ dymem, a dym który ulatuje z jego ust tworzy dziwn± chmurkê.", ch, pObj, NULL, TO_ROOM );
						act( "Niespodziewanie co¶ ci nie wychodzi, krztusisz siê i kaszlaj±c panicznie wypuszczasz z ust resztki dymu.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					default:
						act( "$n próbuje zrobiæ jak±¶ sztuczkê z wypuszczeniem z ust dymu, jednak udaje mu siê jedynie uformowaæ dym w bezkszta³tn± chmurê.", ch, pObj, NULL, TO_ROOM );
						act( "Starasz siê wypu¶ciæ z ust kulê dymu, jednak nie udaje ci siê, a dym przybiera kszta³t nieforemnej chmury.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
				}
			}
		}
		else if ( !str_prefix( arg2, "sieæ" ) || !str_prefix( arg2, "web" ))
		{
			if ( dice( 2, dex - 5 ) >= 15 && dice( 2, con - 8 ) > 6 )
			{
				act( "$n wydycha kilkana¶cie cieniutkich, zwiewnych pasemek dymu, które niespodziewanie ³±cz± siê tworz±c delikatn±, prawie pajêcz±, sieæ w powietrzu!", ch, NULL, NULL, TO_ROOM );
				act( "Wydychasz kilkana¶cie cieniutkich, zwiewnych pasemek dymu, które niespodziewanie ³±cz± siê tworz±c delikatn±, prawie pajêcz±, sieæ w powietrzu!", ch, NULL, NULL, TO_CHAR );
				EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
				return ;
			}
			else
			{
				switch ( number_range ( 1, 5 ) )
				{
					case 1:
						act( "$n nagle robi dziwn± minê, po czym momentalnie dostaje ataku kaszlu.", ch, pObj, NULL, TO_ROOM );
						act( "Próbujesz zrobiæ sztuczkê, jednak w ostatniej chwili dym zacz±³ gry¼æ ciê w gar³o i <&dosta³e¶/dosta³a¶/dosta³o¶> ataku kaszlu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 2:
						act( "Widzisz jak $n koncentruje siê przez chwilkê, aby po chwili wypu¶ciæ z ust niekszta³tn± chmurê dymu.", ch, pObj, NULL, TO_ROOM );
						act( "Koncentrujesz siê przez chwilkê, chc±c wypu¶ciæ z ust chmurê dymu w kszta³cie kuli, jednak nie udaje ci siê to.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 3:
						act( "$n nagle zielenieje na twarzy, a z jego nosa zaczynaj± wylatywaæ szare stru¿ki dymu.", ch, pObj, NULL, TO_ROOM );
						act( "W ostatniej chwili przygotowañ do zrobienia sztuczki krztusisz siê i bezwiednie wypuszczasz dym nosem.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 4:
						act( "$n wydycha szybk± seriê w±skich dymków, które wydaj± siê pe³zaæ w powietrzu jak niepos³usze robaczki, szybko rozp³ywaj±ce siê w powietrzu.", ch, pObj, NULL, TO_ROOM );
						act( "Szybko wydychasz seriê w±skich dymków chc±c z nich uformowaæ pajêczynê, te jednak szybko rozp³ywaj± siê w powietrzu.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					default:
						act( "$n próbuje zrobiæ jak±¶ sztuczkê z wypuszczeniem z ust dymu, jednak udaje mu siê jedynie uformowaæ dym w bezkszta³tn± chmurê.", ch, pObj, NULL, TO_ROOM );
						act( "Starasz siê wypu¶ciæ z ust seriê dymków, jednak nie udaje ci siê, a sam dym przybiera kszta³t nieforemnej chmury.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
				}
			}
		}
		else if ( !str_prefix( arg2, "feniks" ) || !str_prefix( arg2, "phoenix" ) || !str_prefix( arg2, "fenix" ) )
		{
			if ( dice( 2, dex - 10 ) >= 8 && dice( 2, con - 10 ) >= 8 && dice( 2, wis - 10 ) >= 5 )
			{
				act( "$n wydycha serie ma³ych chmurek dymu, które na chwilê uk³adaj± siê w wizerunek feniksa, tylko po to, aby chwilê pó¼niej rozp³ynê³y siê, niczym proch.", ch, NULL, NULL, TO_ROOM );
				act( "Wydychasz serie ma³ych chmurek dymu, które na chwilê uk³adaj± siê w wizerunek feniksa, tylko po to, aby chwilê pó¼niej rozp³ynê³y siê, niczym proch.", ch, NULL, NULL, TO_CHAR );
				EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
				return ;
			}
			else
			{
				switch ( number_range ( 1, 7 ) )
				{
					case 1:
						act( "$n nagle robi dziwn± minê, po czym momentalnie dostaje ataku kaszlu.", ch, pObj, NULL, TO_ROOM );
						act( "Próbujesz zrobiæ sztuczkê, jednak w ostatniej chwili dym zacz±³ gry¼æ ciê w gar³o i <&dosta³e¶/dosta³a¶/dosta³o¶> ataku kaszlu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 2:
						act( "Widzisz jak $n koncentruje siê przez chwilkê, aby po chwili wypu¶ciæ z ust niekszta³tn± chmurê dymu.", ch, pObj, NULL, TO_ROOM );
						act( "Koncentrujesz siê przez chwilkê, chc±c wypu¶ciæ z ust chmurê dymu w kszta³cie linii, jednak nie udaje ci siê to.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 3:
						act( "$n nagle zielenieje na twarzy, a z jego nosa zaczynaj± wylatywaæ szare stru¿ki dymu.", ch, pObj, NULL, TO_ROOM );
						act( "W ostatniej chwili przygotowañ do zrobienia sztuczki krztusisz siê i bezwiednie wypuszczasz dym nosem.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 4:
						act( "$n w wielkim skupieniu wydycha kilkana¶cie dymków, które zaczynaj± uk³adaæ siê w powietrzu w co¶ przypominaj±cego hybrydê szczura z ludzkimi nogami... Czy to by³o zamierzone?", ch, pObj, NULL, TO_ROOM );
						act( "W wielkim skupieniu wydychasz kilkana¶cie dymków, które niespodziewanie zamiast feniksa uk³adaj± siê w co¶ przypominaj±cego po³±czenie szczura z ludzkimi nogami! Okropne.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 5:
						act( "$n, z grymasem na twarzy, wypuszcza z ust kilkana¶cie dymków, które uk³adaj± siê w powietrzu w jaki¶ dziwny ptakopodobny twór, wygl±daj±cy dosyæ ohydnie.", ch, pObj, NULL, TO_ROOM );
						act( "Czuj±c, ¿e co¶ pójdzie ¼le wypuszczasz z ust kilkana¶cie dymków, które uk³adaj± siê w powietrzu w jaki¶ bezkszta³tny, ptakopodobny twór.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 6:
						act( "$n, z wyrazem pewno¶ci siebie na twarzy, wydycha seriê ma³ych dymków, które nagle ³±cz± siê w powietrzu tworz±c pewien du¿y, oble¶ny kszta³t... Hmm, to ciekawe. K±tem oka widzisz, ¿e $n siê rumieni na widok swojego dzie³a.", ch, pObj, NULL, TO_ROOM );
						act( "Wypuszczasz z ust kilkana¶cie ma³ych dymków, które nagle ³±cz± siê w powietrzu, tworz±c naprawdê du¿y, oble¶ny kszta³t. Chyba siê zaraz spalisz ze wstydu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					default:
						act( "$n próbuje zrobiæ jak±¶ sztuczkê z wypuszczeniem z ust dymu, jednak udaje mu siê jedynie uformowaæ dym w bezkszta³tn± chmurê.", ch, pObj, NULL, TO_ROOM );
						act( "Starasz siê wypu¶ciæ z ust kilkana¶cie dymków, jednak nie udaje ci siê, a sam dym przybiera kszta³t nieforemnej chmury.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
				}
			}
		}
		else if ( !str_prefix( arg2, "rogi" ) || !str_prefix( arg2, "horns" ))
		{
			if ( dice( 2, dex - 10 ) >= 9 && dice( 2, con - 6 ) >= 10 )
			{
				act( "$n wydycha dwie grube smugi dymu, które uk³adaj± siê nad $m niczym para wielkich rogów!", ch, NULL, NULL, TO_ROOM );
				act( "Wydychasz dwie grube smugi dymu, które uk³adaj± sie nad tob± niczym para wielkich rogów!", ch, NULL, NULL, TO_CHAR );
				EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
				return ;
			}
			else
			{
				switch ( number_range ( 1, 4 ) )
				{
					case 1:
						act( "$n nagle robi dziwn± minê, po czym momentalnie dostaje ataku kaszlu.", ch, pObj, NULL, TO_ROOM );
						act( "Próbujesz zrobiæ sztuczkê, jednak w ostatniej chwili dym zacz±³ gry¼æ ciê w gar³o i <&dosta³e¶/dosta³a¶/dosta³o¶> ataku kaszlu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 2:
						act( "Widzisz jak $n koncentruje siê przez chwilkê, aby po chwili wypu¶ciæ z ust niekszta³tn± chmurê dymu.", ch, pObj, NULL, TO_ROOM );
						act( "Koncentrujesz siê przez chwilkê, chc±c wypu¶ciæ z ust chmurê dymu w kszta³cie linii, jednak nie udaje ci siê to.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 3:
						act( "$n nagle zielenieje na twarzy, a z jego nosa zaczynaj± wylatywaæ szare stru¿ki dymu.", ch, pObj, NULL, TO_ROOM );
						act( "W ostatniej chwili przygotowañ do zrobienia sztuczki krztusisz siê i bezwiednie wypuszczasz dym nosem.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					default:
						act( "$n próbuje zrobiæ jak±¶ sztuczkê z wypuszczeniem z ust dymu, jednak udaje mu siê jedynie uformowaæ dym w bezkszta³tn± chmurê.", ch, pObj, NULL, TO_ROOM );
						act( "Starasz siê wypu¶ciæ z ust prost± liniê dymu, jednak nie udaje ci siê, a dym przybiera kszta³t nieforemnej chmury.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
				}
			}
		}
		else if ( !str_prefix( arg2, "imiê" ) || !str_prefix( arg2, "name" ))
		{
			if ( dice( 2, dex - 10 ) >= 8 && dice( 2, con - 8 ) >= 9 && dice( 2, wis - 10 ) > 6 )
			{
				act( "$n wypuszcza z ust kilkana¶cie ma³ych dymków, które niespodziewanie tworz± w powietrzu napis '$n'! Niesamowite!", ch, NULL, NULL, TO_ROOM );
				act( "Wypuszczasz z ust kilkana¶cie ma³ych dymków, które niespodziewanie tworz± w powietrzu napis '$n'! ¦wietnie!", ch, NULL, NULL, TO_CHAR );
				EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
				return ;
			}
			else
			{
				switch ( number_range ( 1, 6 ) )
				{
					case 1:
						act( "$n nagle robi dziwn± minê, po czym momentalnie dostaje ataku kaszlu.", ch, pObj, NULL, TO_ROOM );
						act( "Próbujesz zrobiæ sztuczkê, jednak w ostatniej chwili dym zacz±³ gry¼æ ciê w gar³o i <&dosta³e¶/dosta³a¶/dosta³o¶> ataku kaszlu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 2:
						act( "Widzisz jak $n koncentruje siê przez chwilkê, aby po chwili wypu¶ciæ z ust niekszta³tn± chmurê dymu.", ch, pObj, NULL, TO_ROOM );
						act( "Koncentrujesz siê przez chwilkê, chc±c wypu¶ciæ z ust chmurê dymu w kszta³cie linii, jednak nie udaje ci siê to.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 3:
						act( "$n nagle zielenieje na twarzy, a z jego nosa zaczynaj± wylatywaæ szare stru¿ki dymu.", ch, pObj, NULL, TO_ROOM );
						act( "W ostatniej chwili przygotowañ do zrobienia sztuczki krztusisz siê i bezwiednie wypuszczasz dym nosem.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 4:
						act( "$n, z wyrazem pewno¶ci siebie na twarzy, wydycha seriê ma³ych dymków, które nagle ³±cz± siê w powietrzu tworz±c pewien du¿y, oble¶ny kszta³t... Hmm, to ciekawe. K±tem oka widzisz, ¿e $n siê rumieni na widok swojego dzie³a.", ch, pObj, NULL, TO_ROOM );
						act( "Wypuszczasz z ust kilkana¶cie ma³ych dymków, które nagle ³±cz± siê w powietrzu, tworz±c naprawdê du¿y, oble¶ny kszta³t. Chyba siê zaraz spalisz ze wstydu!", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					case 5:
						print_char( ch, "Wydychasz w wielkim skupieniu kilkana¶cie szarych dymków, które niespodziewanie tworz± w powietrzu bezsensowny napis '%s'!", gen_random_str( 4, 8 ) );
						sprintf( buf, "$n wydycha w wielkim skupieniu kilkana¶cie szarych dymków, które niespodziewanie tworz± w powietrzu bezsensowny napis '%s'!\n\r", gen_random_str( 4, 8 ) );
						act( buf, ch, NULL, NULL, TO_ROOM );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
					default:
						act( "$n próbuje zrobiæ jak±¶ sztuczkê z wypuszczeniem z ust dymu, jednak udaje mu siê jedynie uformowaæ dym w bezkszta³tn± chmurê.", ch, pObj, NULL, TO_ROOM );
						act( "Starasz siê wypu¶ciæ z ust kilka dziwnych chmurek dymu, jednak nie udaje ci siê, a dym przybiera kszta³t nieforemnej chmury.", ch, pObj, NULL, TO_CHAR );
						EXT_REMOVE_BIT( ch->act, PLR_SMOKED );
						break;
				}
			}
		}
		else
		{
			send_to_char( "Huh?! Nie znasz takiej sztuczki!\n\r", ch );
			return;
		}
	}


	// Nabijanie fajki
	if ( !str_prefix( arg1, "tamp" ) || !str_prefix( arg1, "nabij" ))
	{
		// Seria zabezpieczen...
		if ( pObj == NULL ) pObj = get_eq_char( ch, WEAR_HOLD );

		if ( pObj == NULL )
		{
			act( "Co chcesz nabiæ?", ch, pObj, NULL, TO_CHAR );
			return ;
		}

		if ( pObj->item_type != ITEM_PIPE )
		{
			send_to_char( "Mo¿esz nabijaæ jedynie fajki!\n\r", ch );
			return ;
		}

		if ( ( qObj = get_obj_carry( ch, arg3, ch ) ) == NULL )
		{
			act( "Czym chcesz nabiæ $h?", ch, pObj, NULL, TO_CHAR );
			return ;
		}

		if ( qObj->item_type != ITEM_WEED )
		{
			pipe_name = capitalize( pObj->name4 );
			sprintf( pipe_name_2, "%s mo¿esz nabiæ jedynie jakim¶ rodzajem ziela.", pipe_name );
			act( pipe_name_2, ch, pObj, NULL, TO_CHAR );
		}
		else if ( pObj->value[ 0 ] == 1 )
		{
			pipe_name = capitalize( pObj->short_descr );
			sprintf( pipe_name_2, "%s jest zapalona, nie mo¿esz jej teraz nabijaæ!", pipe_name );
			act( pipe_name_2, ch, pObj, NULL, TO_CHAR );
			return ;
		}
		else if ( pObj->value[ 1 ] > 0 )
		{
			pipe_name = capitalize( pObj->short_descr );
			sprintf( pipe_name_2, "%s jest ju¿ czym¶ nabita. Przed ponownym nabiciem opró¿nij j±.", pipe_name );
			act( pipe_name_2, ch, pObj, NULL, TO_CHAR );
			return ;
		}
		else
		{
			// Nabijanie fajki, przepisywanie wartosci ziela do fajeczki.
			weed_amount = qObj->value [ 0 ];
			weed_type = qObj->value [ 1 ];
			pObj->value [ 1 ] = weed_amount;
			pObj->value [ 2 ] = weed_type;
			print_char( ch, "Nabijasz %s %s.\n\r", pObj->name4, qObj->name5 );
			sprintf( buf, "$n nabija %s %s.\n\r", pObj->name4, qObj->name5 );
			act( buf, ch, NULL, NULL, TO_ROOM );
			extract_obj( qObj );
			return ;
		}


	}

	// zapalanie
	if ( !str_prefix( arg1, "light" ) || !str_prefix( arg1, "zapal" ))
	{
		pObj = get_obj_carry( ch, arg2, ch );

		if ( pObj == NULL ) pObj = get_eq_char( ch, WEAR_HOLD );

		if ( pObj == NULL )
		{
			act( "Co chcesz zapaliæ?", ch, pObj, NULL, TO_CHAR );
			return ;
		}

		if ( pObj->item_type != ITEM_PIPE )
		{
			send_to_char( "Mo¿esz zapalaæ jedynie fajki!\n\r", ch );
			return ;
		}
		else if ( pObj->value[ 0 ] == 1 )
		{
			pipe_name = capitalize( pObj->short_descr );
			sprintf( pipe_name_2, "%s jest ju¿ zapalona.", pipe_name );
			act( pipe_name_2, ch, pObj, NULL, TO_CHAR );
			return ;
		}
		else if ( pObj->value[ 2 ] == 4 )
		{
			act( "Zawarto¶æ $f jest mokra! Nie dasz rady tego zapaliæ.", ch, pObj, NULL, TO_CHAR );
			act( "Lepiej wyczy¶æ $h i nape³nij j± czym¶ suchym, najlepiej zielem fajkowym.", ch, pObj, NULL, TO_CHAR );
			return ;
		}
		else
		{
			pObj->value [ 0 ] = 1;
			act( "Zapalaj±c $h zaczynasz czuæ przyjemny, delikatny zapach palonego ziela.", ch, pObj, NULL, TO_CHAR );
			act( "$n zapala $h. Czujesz jak w powietrzu zaczyna unosiæ siê lekki zapach palonego ziela.", ch, pObj, NULL, TO_ROOM );
			return ;
		}
	}

	// gaszenie
	if ( !str_prefix( arg1, "extinguish" ) || !str_prefix( arg1, "zga¶" ))
	{

		/*if ( ( pObj = get_obj_carry( ch, arg2, ch ) ) == NULL )
		{
			act( "Co chcesz zgasiæ?", ch, pObj, NULL, TO_CHAR );
			return ;
		}*/

		if ( pObj == NULL ) pObj = get_eq_char( ch, WEAR_HOLD );

		if ( pObj == NULL )
		{
			act( "Co chcesz zgasiæ?", ch, pObj, NULL, TO_CHAR );
			return ;
		}

		if ( pObj->item_type != ITEM_PIPE )
		{
			send_to_char( "Mo¿esz gasiæ jedynie fajki!\n\r", ch );
			return ;
		}
		else if ( pObj->value[ 0 ] == 0 )
		{
			pipe_name = capitalize( pObj->short_descr );
			sprintf( pipe_name_2, "%s jest ju¿ zgaszona.", pipe_name );
			act( pipe_name_2, ch, pObj, NULL, TO_CHAR );
			return ;
		}
		else
		{
			pObj->value [ 0 ] = 0;
			act( "Gasz±c $h widzisz jak ostatnie iskierki ognia bledn± i znikaj±.", ch, pObj, NULL, TO_CHAR );
			act( "$n gasi $h.", ch, pObj, NULL, TO_ROOM );
			return ;
		}
	}

	// czyszczenie / opró¿nianie
	if ( !str_prefix( arg1, "clean" ) || !str_prefix( arg1, "wyczy¶æ" ))
	{

		/*if ( ( pObj = get_obj_carry( ch, arg2, ch ) ) == NULL )
		{
			act( "Co chcesz wyczy¶ciæ?", ch, pObj, NULL, TO_CHAR );
			return ;
		}*/

		if ( pObj == NULL ) pObj = get_eq_char( ch, WEAR_HOLD );

		if ( pObj == NULL )
		{
			act( "Co chcesz wyczy¶ciæ?", ch, pObj, NULL, TO_CHAR );
			return ;
		}

		if ( pObj->item_type != ITEM_PIPE )
		{
			send_to_char( "Mo¿esz czy¶ciæ jedynie fajki!\n\r", ch );
			return ;
		}
		else if ( pObj->value[ 0 ] == 1 )
		{
			act( "Mo¿e lepiej najpierw zga¶ $h?", ch, pObj, NULL, TO_CHAR );
			return ;
		}
		else if ( pObj->value[ 1 ] == 0 )
		{
			act( "Ogl±dasz z dum± $h, po czym pucujesz j± dok³adnie rêkawem. Teraz jest naprawdê czysta!", ch, pObj, NULL, TO_CHAR );
			act( "$n z dum± pucuje $h, u¶miechaj±c siê przy tym tajemniczo.", ch, pObj, NULL, TO_ROOM );
			return ;
		}
		else
		{
			pObj->value [ 1 ] = 0;
			pObj->value [ 2 ] = 0;
			act( "Wysypujesz zawarto¶æ $f. Teraz jest pusta.", ch, pObj, NULL, TO_CHAR );
			act( "$n wysypuje zawarto¶æ $f.", ch, pObj, NULL, TO_ROOM );
			return ;
		}
	}

	send_to_char( "Huh?\n\r", ch );
	return;
}
コード例 #30
0
ファイル: Drakes.cpp プロジェクト: justinabrahms/avendar
void Drakes::AdjustDrake(CHAR_DATA & ch, CHAR_DATA & drake, int stoneType, const Info & info, int level, Age age)
{
    // Set the appropriate strings
    const char * stoneName(material_table[stoneType].name);
    std::string shortDesc(BuildShortDesc(stoneName, age));
    std::string longDesc(shortDesc + " is here.\n");
    longDesc[0] = UPPER(longDesc[0]);
    setName(drake, shortDesc.c_str());
    copy_string(drake.short_descr, shortDesc.c_str());
    copy_string(drake.long_descr, longDesc.c_str());
    copy_string(drake.description, BuildDescription(ch, stoneName, age).c_str());

    // Seed any random values with ch's id
    srand(ch.id + 12345);

    // Adjust damage type and damverb
    drake.dam_type = info.damageType;
    const char * damverb("strike");
    switch (info.damageType)
    {
        case DAM_BASH:
            switch ((rand() + stoneType) % 3)
            {
                case 0: damverb = "slam"; break;
                case 1: damverb = "smash"; break;
                case 2: damverb = "crush"; break;
            }
            break;

        case DAM_SLASH:
            switch ((rand() + stoneType) % 3)
            {
                case 0: damverb = "slice"; break;
                case 1: damverb = "claw"; break;
                case 2: damverb = "talon"; break;
            }
            break;
 
        case DAM_PIERCE:
            switch ((rand() + stoneType) % 2)
            {
                case 0: damverb = "bite"; break;
                case 1: damverb = "strike"; break;
            }
            break;
    }
    copy_string(drake.dam_verb, damverb);

    // Perform basic adjustments
    drake.level = UMAX(1, level + age);
    drake.damroll = (level / 10) + (age * 4);
    drake.hitroll = (level * 2) / 3;
    drake.damage[0] = (level * 2) / 3;
    drake.damage[1] = 4;
    drake.damage[2] = drake.damroll;
    drake.max_hit = dice(level * 4, 19) + 400 + (age * 100);

    // Adjust for damage and hp mods
    drake.damage[0] = (drake.damage[0] * (100 + info.damageMod)) / 100;
    drake.max_hit = (drake.max_hit * (100 + info.hpMod)) / 100;

    // Adjust stats
    for (size_t i(0); i < MAX_STATS; ++i)
    {
        drake.perm_stat[i] = 18 + age;
        drake.mod_stat[i] = 18 + age;
        drake.max_stat[i] = 18 + age;
    }

    // Fill in resistances
    for (size_t i(0); i < info.resistances.size(); ++i)
        drake.resist[info.resistances[i].type] = info.resistances[i].modBase + (age * info.resistances[i].modStep);

    // Restore random seed
    srand(time(0));

    // Determine duration until next age level up
    int duration((age + 1) * 260);
    if (age == Ancient) duration = -1;
    else duration = (duration * (100 + info.maturationMod)) / 100;

    // Mark the drake's stone type and age in the modifier and level fields
    AFFECT_DATA af = {0};
    af.where    = TO_AFFECTS;
    af.type     = gsn_wakenedstone;
    af.modifier = stoneType;
    af.level    = age;
    af.duration = duration;
    affect_to_char(&drake, &af);

    // Adjust the drake's level for overwhelm
    drake.level += SpecialCount(drake, Overwhelm);
}