예제 #1
0
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;

}
예제 #2
0
void do_eat(struct char_data *ch, char *argument, int cmd)
{
	char buf[100];
	struct obj_data *temp;
	struct affected_type af;

	one_argument(argument,buf);

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

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

	if(GET_COND(ch,FULL)>20) /* Stomach full */
	{	
		act("You are to full to eat more!",FALSE,ch,0,0,TO_CHAR);
		return;
	}

	act("$n eats $p",TRUE,ch,temp,0,TO_ROOM);
	act("You eat the $o.",FALSE,ch,temp,0,TO_CHAR);

	gain_condition(ch,FULL,temp->obj_flags.value[0]);

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

	if(temp->obj_flags.value[3] && (GET_LEVEL(ch) < 21)) /* The shit was poisoned ! */
	{
		act("Ooups, it tasted rather strange ?!!?",FALSE,ch,0,0,TO_CHAR);
		act("$n coughs and utters some strange sounds.",FALSE,ch,0,0,TO_ROOM);

		af.type = SPELL_POISON;
		af.duration = temp->obj_flags.value[0]*2;
		af.modifier = 0;
		af.location = APPLY_NONE;
		af.bitvector = AFF_POISON;
		affect_join(ch,&af, FALSE, FALSE);
	}

	extract_obj(temp);
}
예제 #3
0
파일: limits.c 프로젝트: matthewbode/mg2
/* Update PCs, NPCs, and objects */
void point_update(void)
{
  struct char_data *i, *next_char;
  struct obj_data *j, *next_thing, *jj, *next_thing2;

  /* characters */
  for (i = character_list; i; i = next_char) {
    next_char = i->next;
	
    gain_condition(i, FULL, -1);
    gain_condition(i, DRUNK, -1);
    gain_condition(i, THIRST, -1);
	
    if (GET_POS(i) >= POS_STUNNED) {
      GET_HIT(i) = MIN(GET_HIT(i) + hit_gain(i), GET_MAX_HIT(i));
      GET_MANA(i) = MIN(GET_MANA(i) + mana_gain(i), GET_MAX_MANA(i));
      GET_MOVE(i) = MIN(GET_MOVE(i) + move_gain(i), GET_MAX_MOVE(i));
      if (AFF_FLAGGED(i, AFF_POISON))
	if (damage(i, i, 2, SPELL_POISON) == -1)
	  continue;	/* Oops, they died. -gg 6/24/98 */
      if (GET_POS(i) <= POS_STUNNED)
	update_pos(i);
    } else if (GET_POS(i) == POS_INCAP) {
      if (damage(i, i, 1, TYPE_SUFFERING) == -1)
	continue;
    } else if (GET_POS(i) == POS_MORTALLYW) {
      if (damage(i, i, 2, TYPE_SUFFERING) == -1)
	continue;
    }
    if (!IS_NPC(i)) {
      update_char_objects(i);
      if (GET_LEVEL(i) < idle_max_level)
	check_idling(i);
    }
  }

  /* objects */
  for (j = object_list; j; j = next_thing) {
    next_thing = j->next;	/* Next in object list */

    /* If this is a corpse */
    if (IS_CORPSE(j)) {
      /* timer count down */
      if (GET_OBJ_TIMER(j) > 0)
	GET_OBJ_TIMER(j)--;

      if (!GET_OBJ_TIMER(j)) {

	if (j->carried_by)
	  act("$p decays in your hands.", FALSE, j->carried_by, j, 0, TO_CHAR);
	else if ((IN_ROOM(j) != NOWHERE) && (world[IN_ROOM(j)].people)) {
	  act("A quivering horde of maggots consumes $p.",
	      TRUE, world[IN_ROOM(j)].people, j, 0, TO_ROOM);
	  act("A quivering horde of maggots consumes $p.",
	      TRUE, world[IN_ROOM(j)].people, j, 0, TO_CHAR);
	}
	for (jj = j->contains; jj; jj = next_thing2) {
	  next_thing2 = jj->next_content;	/* Next in inventory */
	  obj_from_obj(jj);

	  if (j->in_obj)
	    obj_to_obj(jj, j->in_obj);
	  else if (j->carried_by)
	    obj_to_room(jj, IN_ROOM(j->carried_by));
	  else if (IN_ROOM(j) != NOWHERE)
	    obj_to_room(jj, IN_ROOM(j));
	  else
	    core_dump();
	}
	extract_obj(j);
      }
    }
    /* If the timer is set, count it down and at 0, try the trigger */
    /* note to .rej hand-patchers: make this last in your point-update() */
    else if (GET_OBJ_TIMER(j)>0) {
      GET_OBJ_TIMER(j)--; 
      if (!GET_OBJ_TIMER(j))
        timer_otrigger(j);
    }
  }
}
예제 #4
0
void regen_update( void ) {
    CharData *i, *next_char;
    int hit, mana, move;
    int vivify_level;

    for( i = character_list; i; i = next_char )
    {
        next_char = i->next;

        if(affected_by_spell(i, SKILL_EMACIATED) && (GET_COND(i, HUNGER) != 0 || IS_VAMPIRE(i)) && GET_COND(i, THIRST) != 0) {
            if(!affected_by_spell(i, SKILL_EMACIATED_MANA) && !affected_by_spell(i, SKILL_EMACIATED_HIT))
                affect_from_char(i, SKILL_EMACIATED);
            else if(percentSuccess(4)) {
                affect_from_char(i, SKILL_EMACIATED_MANA);
                affect_from_char(i, SKILL_EMACIATED_HIT);
            }
        }

        // Dwarves sober up 3x faster than most races (unless they drink more...)
        if(IS_DWARF(i) && !number(0, 35))
            gain_condition(i, DRUNK, -1);

        vivify_level = spell_level(i, SPELL_VIVIFY);
        affect_from_char(i, SPELL_VIVIFY);
        if(GET_POS(i) <= POS_MEDITATING) {
            add_affect(i, i, SPELL_VIVIFY, MIN(vivify_level + 1, 100), APPLY_NONE, 0, -1,
                    0, FALSE, FALSE, FALSE, FALSE);
        }

        if(GET_POS(i) >= POS_MORTALLYW)
        {
            hit = hit_gain(i);
            mana = mana_gain(i);
            move = move_gain(i);

            if(affected_by_spell(i, SPELL_VIVIFY)) {
                if(hit > 0)
                    hit += spell_level(i, SPELL_VIVIFY) * GET_MAX_HIT(i)/600;
                if(mana > 0)
                    mana += spell_level(i, SPELL_VIVIFY) * GET_MAX_MANA(i)/600;
                if(move > 0)
                    move += spell_level(i, SPELL_VIVIFY) * GET_MAX_MOVE(i)/600;
            }

            // Regeneration is increased on pvp holidays.  If you're incapactitated, you will
            // eventually recover.
            if(pvpHoliday(i)) {
                if (GET_POS(i) < POS_SLEEPING)
                    hit = 20;
                else {
                    hit  = (hit  > 0) ? hit *3 : 20;
                    mana = (mana > 0) ? mana*2 : 40;
                    move = (move > 0) ? move*2 : 40;
                }
            }
                

            // 72 seconds per tick...
            if(hit < 0 || GET_HIT(i) < GET_MAX_HIT(i)) {
                if(hit>0)
                    GET_HIT(i) += hit/72 + (hit % 72 > number(0, 71)? 1:0);
                else
                    GET_HIT(i)  = MAX(GET_HIT(i) + hit/72 + (-hit % 72 > number(0, 71)?-1:0), -9);
            }
            else {
                int surplus = (GET_HIT(i) - GET_MAX_HIT(i));
                GET_HIT(i) -= surplus / 72 + (surplus % 72 > number(0, 71)? 1:0);
            }


            if(mana>0)
                GET_MANA(i) = MAX(MIN(GET_MANA(i) + mana/72 + (mana % 72 > number(0, 71)?1:0), GET_MAX_MANA(i)), 0);
            else
                GET_MANA(i) = MIN(GET_MANA(i) + mana/72 + (-mana % 72 > number(0, 71)?-1:0), GET_MAX_MANA(i));

            if(move>0)
                GET_MOVE(i) = MIN(GET_MOVE(i) + move/72 + (move % 72 > number(0, 71)?1:0), GET_MAX_MOVE(i));
            else
                GET_MOVE(i) = MAX(MIN(GET_MOVE(i) + move/72 + (-move % 72 > number(0, 71)?-1:0), GET_MAX_MOVE(i)), 0);

            update_pos(i);
        }
    }
}
예제 #5
0
/*
** Update PCs, NPCs, and objects
*/
void
point_update( void )
{
    int slot;

    void update_char_objects(CharData * ch); /* handler.c */
    void extract_obj(ObjData * obj);	     /* handler.c */
    void update_char_quests(CharData * ch);  /* quest.c */
    CharData *i, *next_char;
    ObjData  *j, *next_thing, *jj, *next_thing2, *debugnext;
    int loopvar;

    /* characters */
    for( i = character_list; i; i = next_char )
    {
        next_char = i->next;

        // state flags
        i->tickstate = 0;

        /* dismount anyone who's gotten separated from their steed */
        /* Note that it's superfluous to check for both rider AND mount */
        if (i->rider && i->rider->in_room != i->in_room) {
            i->rider->mount = NULL;
            i->rider = NULL;
        }

        /* Prayer timer */
        if (i->player_specials->saved.prayer_time > 0) {
            if (i->player_specials->saved.prayer_time == 1) {
                i->player_specials->saved.prayer_time = 0;
                send_to_char("Your prayers will be heard once again.\r\n", i);
            } else
                i->player_specials->saved.prayer_time -= 1;
        }

        for(slot = 0; slot<4; slot++) {
            if (COOLDOWN(i, slot) ) {
                COOLDOWN(i, slot) -= 1;
                if (!COOLDOWN(i, slot) ) {
                    switch( GET_CLASS(i) ) {
                        case CLASS_DEATH_KNIGHT:
                            break;
                        case CLASS_SOLAMNIC_KNIGHT:
                            break;
                        case CLASS_MAGIC_USER:
                            break;
                        case CLASS_SHADOW_DANCER:
                            if(slot == SLOT_SLIPPERY_MIND)
                                break;
                            else if(slot == SLOT_NODESHIFT)
                                sendChar(i, "You may once again shift your spectrum.\r\n");
                            else sendChar(i, "ERROR!\r\n");
                            break;
                        case CLASS_THIEF:
                            if(slot== SLOT_BLACKJACK) {
                                sendChar(i, "You are able to use blackjack again.\r\n");
                                break;
                            }
                            else sendChar(i, "ERROR!\r\n");
                        case CLASS_ASSASSIN:
                            if(slot == SLOT_DETERRENCE)
                                sendChar(i, "You are able to use deterrence again.\r\n");
                            else sendChar(i, "ERROR!\r\n");
                            break;
                        case CLASS_CLERIC:
                            if(slot == SLOT_SHADOW_FORM)
                                sendChar(i, "You are ready to enter shadow form again..\r\n");
                            else sendChar(i, "ERROR!\r\n");
                        case CLASS_WARRIOR:
                            if(slot == SLOT_REDOUBT)
                                sendChar(i, "You can shield yourself again.\r\n");
                            else if(slot == SLOT_COMMANDING_SHOUT)
                                sendChar(i, "You can shout commands again.\r\n");
                            else sendChar(i, "ERROR!\r\n");
                            break;
                        case CLASS_SHOU_LIN:
                            break;
                        case CLASS_RANGER:
                            break;
                        case CLASS_NECROMANCER:
                            if(slot == SLOT_QUICKEN)
                                sendChar(i, "You may once again rise from the grave.\r\n");
                            else if(slot == SLOT_METAMORPHOSIS)
                                sendChar(i, "You may once again metamorphisize.\r\n");
                            else sendChar(i, "ERROR!\r\n");
                            break;

                        default:
                            sendChar(i, "ERROR!\r\n");
                            break;
                    }
                }
            }
        }

        if( IS_AFFECTED(i, AFF_PLAGUE )) infectious(i);

        if( !IS_NPC(i) )
        {
            update_char_objects(i);
            if( GET_LEVEL(i) < LVL_GOD )
                check_idling(i);
            update_char_quests(i);
        }
        gain_condition(i, HUNGER, IS_AFFECTED(i, AFF_REGENERATE)? -2:-1);
        gain_condition(i, DRUNK, -1);

        /* Amara get thirsty in different ways */
        if (IS_AMARA(i)) {
            if (IN_ROOM(i) >= 0 && IN_ROOM(i) <= top_of_world) {
                switch (SECT(IN_ROOM(i))) {
                    case SECT_WATER_SWIM:
                    case SECT_WATER_NOSWIM:
                        gain_condition(i, THIRST, 1);
                        break;
                    case SECT_UNDERWATER:
                    case SECT_UNDERWATER_RIVER:
                        gain_condition(i, THIRST, 24);
                        break;
                    default:
                        gain_condition(i, THIRST, -2);
                        break;
                }
            } else gain_condition(i, THIRST, -2);
        } else gain_condition(i, THIRST, -1);
    }/* for */

    debugnext = NULL;
    /* objects */
    for( j = object_list; j; j = next_thing )
    {
        next_thing = j->next;	/* Next in object list */
        debugnext = j;		// we didn't crash if we got here

        if( IS_SET_AR( j->obj_flags.extra_flags, ITEM_TIMED ))
        {
            if( GET_OBJ_TIMER(j) > 0 )
                GET_OBJ_TIMER(j)--;

            if (GET_OBJ_TIMER(j) == 0) {
                if(contains_soulbound(j)) {
                    GET_OBJ_TIMER(j) = 1;
                    continue;
                }

                if (SCRIPT_CHECK(j, OTRIG_TIMER)) {
                    REMOVE_BIT_AR(j->obj_flags.extra_flags, ITEM_TIMED);
                    timer_otrigger(j);
                    continue;    // don't do anything more with this
                }
            }

            if( GET_OBJ_TYPE(j) == ITEM_KEY )
            {
                static char *keyVaporMsgs[] = {
                    "$p vanishes with a flash.",
                    "$p begins to shake violently.",
                    "$p begins to vibrate.",
                    "$p begins to hum.",
                    "$p begins to glow."
                };

                if( GET_OBJ_TIMER(j) < (sizeof( keyVaporMsgs )/sizeof( *keyVaporMsgs )))
                {
                    int vaporMsg = GET_OBJ_TIMER(j);

                    if( j->carried_by )
                        act( keyVaporMsgs[ vaporMsg ], FALSE, j->carried_by, j, 0, TO_CHAR);

                    else if( j->worn_by )
                    {
                        act( keyVaporMsgs[ vaporMsg ], FALSE, j->worn_by, j, 0, TO_CHAR);
                        for( loopvar = 0; loopvar < NUM_WEARS; loopvar++ )
                        {
                            if( j->worn_by->equipment[loopvar] == j )
                                j->worn_by->equipment[loopvar] = 0;
                        }
                    }
                    else if( j->in_room != NOWHERE && world[j->in_room].people )
                    {
                        act( keyVaporMsgs[ vaporMsg ], FALSE, world[j->in_room].people, j, 0, TO_CHAR);
                        act( keyVaporMsgs[ vaporMsg ], FALSE, world[j->in_room].people, j, 0, TO_ROOM);
                    }
                    extract_obj(j);
                    continue;
                }/* ITEM_KEY has timed out */
            }/* if ITEM_KEY */
            else if (GET_OBJ_TYPE(j) == ITEM_AFFECT)
            {
                if (!GET_OBJ_TIMER(j)) {
                    if (j->in_room != NOWHERE && world[j->in_room].people) {
                        act(j->action_description, FALSE, world[j->in_room].people,
                                j, 0, TO_CHAR);
                        act(j->action_description, FALSE, world[j->in_room].people,
                                j, 0, TO_ROOM);
                    }
                    extract_obj(j);
                    continue; // object gone, don't act further on it!
                }
            }
            else if( !GET_OBJ_TIMER(j) )
            {
                /* The object timed out - delete it */
                if( j->carried_by )
                    act( "$p crumbles to dust and is blown away.", FALSE, j->carried_by, j, 0, TO_CHAR );

                else if( j->worn_by )
                {
                    act("$p crumbles to dust and is blown away.", FALSE, j->worn_by, j, 0, TO_CHAR);
                    unequip_char( j->worn_by, j->worn_at );
                }
                else if( j->in_room != NOWHERE && world[j->in_room].people )
                {
                    act( "$p crumbles to dust and is blown away.",
                            FALSE, world[j->in_room].people, j, 0, TO_CHAR);
                    act( "$p crumbles to dust and is blown away.",
                            FALSE, world[j->in_room].people, j, 0, TO_ROOM);
                }
                extract_obj(j);
                continue; // object gone, don't act further on it!
            }
        } /* if OBJ_TIMED */

        /* if this looks like a portal */
        if ( (GET_OBJ_RNUM(j) >= 0 && GET_OBJ_RNUM(j) <= top_of_objt) &&
                obj_index[GET_OBJ_RNUM(j)].func == portal_proc &&
                GET_OBJ_TYPE(j) == ITEM_OTHER )
        { /* Mage created portals are type other, permanent portals are type portal. */
            /* Permanent portals thus don't decay. */
            if (GET_OBJ_VAL(j, 2) > 0)
                GET_OBJ_VAL(j,2)--;
        }
        /*
         ** Digger
         */
        /* If this is a corpse */
        if ((GET_OBJ_TYPE(j) == ITEM_CONTAINER) && GET_OBJ_VAL(j, 3)) {
            /* timer count down */
            if (GET_OBJ_TIMER(j) > 0)
                GET_OBJ_TIMER(j)--;

            // PC corpses which are empty will decay eventually..
            if(!CAN_WEAR(j, ITEM_WEAR_TAKE) && !(j->contains))
            {
                GET_OBJ_TIMER(j) = MAX(GET_OBJ_TIMER(j) / 3, 0);
            }

            if (!GET_OBJ_TIMER(j)) {
                if(contains_soulbound(j)) {
                    GET_OBJ_TIMER(j) = 1;
                    continue;
                }

                if (j->carried_by)
                    act("$p decays in your hands.", FALSE, j->carried_by, j, 0, TO_CHAR);
                
                else if ((j->in_room != NOWHERE) && (world[j->in_room].people)) {
                    static char *decay_messages[] = {
                        "A quivering hoard of maggots consumes $p.",
                        "A flock of vultures swoop down from the sky to devour $p.",
                        "The $p rots and decays as the shards of bone are blown to the four winds.",
                        "The $p rots and decays leaving behind the pungent stench of death.",
                        "A bolt of holy fire streaks from the heavens to burn the corpse of $p to ash.",
                        "The $p rots to ash and is swept away by the winds of time."
                    };
                    int decay_idx = (int)( random() % ( sizeof( decay_messages ) / sizeof( *decay_messages )));

                    act( decay_messages[ decay_idx ], TRUE, world[j->in_room].people, j, 0, TO_ROOM);
                    act( decay_messages[ decay_idx ], TRUE, world[j->in_room].people, j, 0, TO_CHAR);
                }/* JBP */
                
                for (jj = j->contains; jj; jj = next_thing2) {
                    next_thing2 = jj->next_content;	/* Next in inventory */
                    obj_from_obj(jj);

                    if (j->in_obj) {
                        if ( GET_OBJ_TYPE(j) != ITEM_KEY    &&
                                GET_OBJ_TYPE(j) != ITEM_SCROLL &&
                                GET_OBJ_TYPE(j) != ITEM_POTION &&
                                GET_OBJ_TYPE(j) != ITEM_DUST   &&
                                (GET_OBJ_VNUM(j) == 1460 ||
                                GET_OBJ_VNUM(j) == 1461 ||
                                GET_OBJ_VNUM(j) == 1462   ) )
                            continue;  // Refrigeration to keep food from rotting.
                        obj_to_obj(jj, j->in_obj);
                    }
                    else if (j->carried_by)
                        obj_to_room(jj, j->carried_by->in_room);
                    else if (j->in_room != NOWHERE)
                        obj_to_room(jj, j->in_room);
                    else
                    {
                        /* OLD WAY: assert(FALSE); */
                        mudlog(NRM, LVL_IMMORT, TRUE, "SYSERR: Something is wrong with a container." );
                        obj_to_room(jj, real_room(1201));
                    }
                }
                extract_obj(j);
            }
        }

        /* Imhotep: Added support for ITEM_TROPHY pieces that decay after
         * a given MUD date */        
        if(IS_OBJ_STAT(j, ITEM_TROPHY)) {
            if(GET_OBJ_TIMER(j) < TICKS_SO_FAR) {
                if (j->carried_by)
                    act("$p shimmers and vanishes out of your hands!", FALSE, j->carried_by, j, 0,
                            TO_CHAR);
                else if (j->worn_by) {
                    act("$p shimmers and vanishes!", FALSE, j->worn_by, j, 0, TO_CHAR);
                    unequip_char(j->worn_by, j->worn_at);
                } else if (j->in_room != NOWHERE && world[j->in_room].people) {
                    act("$p shimmers and vanishes!", FALSE,
                            world[j->in_room].people, j, 0, TO_CHAR);
                    act("$p shimmers and vanishes!", FALSE,
                            world[j->in_room].people, j, 0, TO_ROOM);
                }
                extract_obj(j);
                continue;
            }
        }
    }
}/* point_update */
예제 #6
0
void fire_effect(void *vo, int level, int dam, int target)
{
	if (target == TARGET_ROOM)  /* nail objects on the floor */
	{
		ROOM_INDEX_DATA *room = (ROOM_INDEX_DATA *) vo;
		OBJ_DATA *obj, *obj_next;

		for (obj = room->contents; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			fire_effect(obj,level,dam,TARGET_OBJ);
		}
		return;
	}

	if (target == TARGET_CHAR)   /* do the effect on a victim */
	{
		CHAR_DATA *victim = (CHAR_DATA *) vo;
		OBJ_DATA *obj, *obj_next;

	/* chance of blindness */
		if (!IS_AFFECTED(victim,AFF_BLIND)
			&&  !saves_spell(level / 4 + dam / 20, victim,DAM_FIRE))
		{
			AFFECT_DATA af;
			act("$n is blinded by smoke!",victim,NULL,NULL,TO_ROOM);
			act("Your eyes tear up from smoke...you can't see a thing!", victim,NULL,NULL,TO_CHAR);

			af.where        = TO_AFFECTS;
			af.type         = skill_lookup("fire breath");
			af.level        = level;
			af.duration     = number_range(0,level/10);
			af.location     = APPLY_HITROLL;
			af.modifier     = -4;
			af.bitvector    = AFF_BLIND;

			affect_to_char(victim,&af);
		}

	/* getting thirsty */
		if (!IS_NPC(victim))
			gain_condition(victim,COND_THIRST,dam/20);

	/* let's toast some gear! */
		for (obj = victim->carrying; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;

			fire_effect(obj,level,dam,TARGET_OBJ);
		}
		return;
	}

	if (target == TARGET_OBJ)  /* toast an object */
	{
		OBJ_DATA *obj = (OBJ_DATA *) vo;
		OBJ_DATA *t_obj,*n_obj;
		int chance = level / 4 + dam / 10;
		char *msg;

		if (IS_OBJ_STAT(obj,ITEM_BURN_PROOF)
			||  IS_OBJ_STAT(obj,ITEM_NOPURGE)
			||  number_range(0,4) == 0)
			return;

		if (chance > 25)
			chance = (chance - 25) / 2 + 25;
		if (chance > 50)
			chance = (chance - 50) / 2 + 50;

		if (IS_OBJ_STAT(obj,ITEM_BLESS))
			chance -= 5;
		chance -= obj->level * 2;

		switch ( obj->item_type )
		{
			default:             
			return;
			case ITEM_CONTAINER:
			msg = "$p ignites and burns!";
			break;
			case ITEM_POTION:
			chance += 25;
			msg = "$p bubbles and boils!";
			break;
			case ITEM_SCROLL:
			chance += 50;
			msg = "$p crackles and burns!";
			break;
			case ITEM_STAFF:
			chance += 10;
			msg = "$p smokes and chars!";
			break;
			case ITEM_WAND:
			msg = "$p sparks and sputters!";
			break;
			case ITEM_FOOD:
			msg = "$p blackens and crisps!";
			break;
			case ITEM_PILL:
			msg = "$p melts and drips!";
			break;
		}

		chance = URANGE(5,chance,95);

		if (number_percent() > chance)
			return;

		if (obj->carried_by != NULL)
			act( msg, obj->carried_by, obj, NULL, TO_ALL );
		else if (obj->in_room != NULL && obj->in_room->people != NULL)
			act(msg,obj->in_room->people,obj,NULL,TO_ALL);

		if (obj->contains)
		{
			/* dump the contents */

			for (t_obj = obj->contains; t_obj != NULL; t_obj = n_obj)
			{
				n_obj = t_obj->next_content;
				obj_from_obj(t_obj);
				if (obj->in_room != NULL)
					obj_to_room(t_obj,obj->in_room);
				else if (obj->carried_by != NULL)
					obj_to_room(t_obj,obj->carried_by->in_room);
				else
				{
					extract_obj(t_obj);
					continue;
				}
				fire_effect(t_obj,level/2,dam/2,TARGET_OBJ);
			}
		}

		extract_obj( obj );
		return;
	}
}
예제 #7
0
void cold_effect(void *vo, int level, int dam, int target)
{
	if (target == TARGET_ROOM) /* nail objects on the floor */
	{
		ROOM_INDEX_DATA *room = (ROOM_INDEX_DATA *) vo;
		OBJ_DATA *obj, *obj_next;
		
		for (obj = room->contents; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			cold_effect(obj,level,dam,TARGET_OBJ);
		}
		return;
	}

	if (target == TARGET_CHAR) /* whack a character */
	{
		CHAR_DATA *victim = (CHAR_DATA *) vo;
		OBJ_DATA *obj, *obj_next;
		
	/* chill touch effect */
		if (!saves_spell(level/4 + dam / 20, victim, DAM_COLD))
		{
			AFFECT_DATA af;

			act("$n turns blue and shivers.",victim,NULL,NULL,TO_ROOM);
			act("A chill sinks deep into your bones.",victim,NULL,NULL,TO_CHAR);
			af.where     = TO_AFFECTS;
			af.type      = skill_lookup("chill touch");
			af.level     = level;
			af.duration  = 6;
			af.location  = APPLY_STR;
			af.modifier  = -1;
			af.bitvector = 0;
			affect_join( victim, &af );
		}

	/* hunger! (warmth sucked out */
		if (!IS_NPC(victim))
			gain_condition(victim,COND_HUNGER,dam/20);

	/* let's toast some gear */
		for (obj = victim->carrying; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			cold_effect(obj,level,dam,TARGET_OBJ);
		}
		return;
	}

	if (target == TARGET_OBJ) /* toast an object */
	{
		OBJ_DATA *obj = (OBJ_DATA *) vo;
		int chance = level / 4 + dam / 10;
		char *msg;

		if (IS_OBJ_STAT(obj,ITEM_BURN_PROOF)
			||  IS_OBJ_STAT(obj,ITEM_NOPURGE)
			||  number_range(0,4) == 0)
			return;

		if (chance > 25)
			chance = (chance - 25) / 2 + 25;
		if (chance > 50)
			chance = (chance - 50) / 2 + 50;

		if (IS_OBJ_STAT(obj,ITEM_BLESS))
			chance -= 5;

		chance -= obj->level * 2;

		switch(obj->item_type)
		{
			default:
			return;
			case ITEM_POTION:
			msg = "$p freezes and shatters!";
			chance += 25;
			break;
			case ITEM_DRINK_CON:
			msg = "$p freezes and shatters!";
			chance += 5;
			break;
		}

		chance = URANGE(5,chance,95);

		if (number_percent() > chance)
			return;

		if (obj->carried_by != NULL)
			act(msg,obj->carried_by,obj,NULL,TO_ALL);
		else if (obj->in_room != NULL && obj->in_room->people != NULL)
			act(msg,obj->in_room->people,obj,NULL,TO_ALL);

		extract_obj(obj);
		return;
	}
}
예제 #8
0
void do_drink(struct char_data *ch, char *argument, int cmd)
{
	char buf[100];
	struct obj_data *temp;
	struct affected_type af;
	int amount,i;


	one_argument(argument,buf);

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

	if (temp->obj_flags.type_flag!=ITEM_DRINKCON)
	{
		act("You can't drink from that!",FALSE,ch,0,0,TO_CHAR);
		return;
	}

	if((GET_COND(ch,DRUNK)>10)&&(GET_COND(ch,THIRST)>0)) /* The pig is drunk */
	{
		act("You simply fail to reach your mouth!", FALSE, ch, 0, 0, TO_CHAR);
		act("$n tried to drink but missed $s mouth!", TRUE, ch, 0, 0, TO_ROOM);
		return;
	}

	if((GET_COND(ch,FULL)>20)&&(GET_COND(ch,THIRST)>0)) /* Stomach full */
	{
		act("Your stomach can't contain anymore!",FALSE,ch,0,0,TO_CHAR);
		return;
	}

  if (temp->obj_flags.type_flag==ITEM_DRINKCON){
		if(temp->obj_flags.value[1]>0)  /* Not empty */
		{	
			sprintf(buf,"$n drinks %s from $p",drinks[temp->obj_flags.value[2]]);
			act(buf, TRUE, ch, temp, 0, TO_ROOM);
			sprintf(buf,"You drink the %s.\n\r",drinks[temp->obj_flags.value[2]]);
			send_to_char(buf,ch);

			if (drink_aff[temp->obj_flags.value[2]][DRUNK] > 0 )
				amount = (25-GET_COND(ch,THIRST))/drink_aff[temp->obj_flags.value[2]][DRUNK];
			else
		  	amount = number(3,10);

			amount = MIN(amount,temp->obj_flags.value[1]);

			weight_change_object(temp, -amount);  /* Subtract amount */

			gain_condition(ch,DRUNK,(int)((int)drink_aff
				[temp->obj_flags.value[2]][DRUNK]*amount)/4);

			gain_condition(ch,FULL,(int)((int)drink_aff
				[temp->obj_flags.value[2]][FULL]*amount)/4);

			gain_condition(ch,THIRST,(int)((int)drink_aff
				[temp->obj_flags.value[2]][THIRST]*amount)/4);

			if(GET_COND(ch,DRUNK)>10)
				act("You feel drunk.",FALSE,ch,0,0,TO_CHAR);

			if(GET_COND(ch,THIRST)>20)
				act("You do not feel thirsty.",FALSE,ch,0,0,TO_CHAR);

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

			if(temp->obj_flags.value[3]) /* The shit was poisoned ! */
			{
				act("Ooups, it tasted rather strange ?!!?",FALSE,ch,0,0,TO_CHAR);
				act("$n chokes and utters some strange sounds.",
				   TRUE,ch,0,0,TO_ROOM);
				af.type = SPELL_POISON;
				af.duration = amount*3;
				af.modifier = 0;
				af.location = APPLY_NONE;
				af.bitvector = AFF_POISON;
				affect_join(ch,&af, FALSE, FALSE);
			}

			/* empty the container, and no longer poison. */
			temp->obj_flags.value[1]-= amount;
			if(!temp->obj_flags.value[1]) {  /* The last bit */
				temp->obj_flags.value[2]=0;
				temp->obj_flags.value[3]=0;
				name_from_drinkcon(temp);
			}
			return;

		}
	}

	act("It's empty already.",FALSE,ch,0,0,TO_CHAR);
	
	return;
}
예제 #9
0
void do_sip(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)
	{
		act("You can't sip from that!",FALSE,ch,0,0,TO_CHAR);
		return;
	}

	if(GET_COND(ch,DRUNK)>10) /* The pig is drunk ! */
	{
		act("You simply fail to reach your mouth!",FALSE,ch,0,0,TO_CHAR);
		act("$n tries to sip, but fails!",TRUE,ch,0,0,TO_ROOM);
		return;
	}

	if(!temp->obj_flags.value[1])  /* Empty */
	{
		act("But there is nothing in it?",FALSE,ch,0,0,TO_CHAR);
		return;
	}

	act("$n sips from the $o",TRUE,ch,temp,0,TO_ROOM);
	sprintf(buf,"It tastes like %s.\n\r",drinks[temp->obj_flags.value[2]]);
	send_to_char(buf,ch);

	gain_condition(ch,DRUNK,(int)(drink_aff[temp->obj_flags.value[2]][DRUNK]/4));

	gain_condition(ch,FULL,(int)(drink_aff[temp->obj_flags.value[2]][FULL]/4));

	gain_condition(ch,THIRST,(int)(drink_aff[temp->obj_flags.value[2]][THIRST]/4));

	weight_change_object(temp, -1);  /* Subtract one unit */

	if(GET_COND(ch,DRUNK)>10)
		act("You feel drunk.",FALSE,ch,0,0,TO_CHAR);

	if(GET_COND(ch,THIRST)>20)
		act("You do not feel thirsty.",FALSE,ch,0,0,TO_CHAR);

	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("But it also had a strange taste!",FALSE,ch,0,0,TO_CHAR);

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

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

	if(!temp->obj_flags.value[1])  /* The last bit */
	{
		temp->obj_flags.value[2]=0;
		temp->obj_flags.value[3]=0;
		name_from_drinkcon(temp);
	}

	return;

}
예제 #10
0
/*
 * Update all chars, including mobs.
*/
void char_update( void )
{   
    CHAR_DATA *ch;
    CHAR_DATA *ch_next;
    CHAR_DATA *ch_quit;

    ch_quit	= NULL;

    /* update save counter */
    save_number++;

    if (save_number > 29)
	save_number = 0;

    for ( ch = char_list; ch != NULL; ch = ch_next )
    {
	AFFECT_DATA *paf;
	AFFECT_DATA *paf_next;

	ch_next = ch->next;

        if ( ch->timer > 30 )
            ch_quit = ch;

	if ( ch->position >= POS_STUNNED )
	{
            /* check to see if we need to go home */
            if (IS_NPC(ch) && ch->zone != NULL && ch->zone != ch->in_room->area
            && ch->desc == NULL &&  ch->fighting == NULL 
	    && !IS_AFFECTED(ch,AFF_CHARM) && number_percent() < 5)
            {
            	act("$n wanders on home.",ch,NULL,NULL,TO_ROOM);
            	extract_char(ch,TRUE);
            	continue;
            }

	    if ( ch->hit  < ch->max_hit )
		ch->hit  += hit_gain(ch);
	    else
		ch->hit = ch->max_hit;

	    if ( ch->mana < ch->max_mana )
		ch->mana += mana_gain(ch);
	    else
		ch->mana = ch->max_mana;

	    if ( ch->move < ch->max_move )
		ch->move += move_gain(ch);
	    else
		ch->move = ch->max_move;
	}

	if ( ch->position == POS_STUNNED )
	    update_pos( ch );

	if ( !IS_NPC(ch) && ch->level < LEVEL_IMMORTAL )
	{
	    OBJ_DATA *obj;

	    if ( ( obj = get_eq_char( ch, WEAR_LIGHT ) ) != NULL
	    &&   obj->item_type == ITEM_LIGHT
	    &&   obj->value[2] > 0 )
	    {
		if ( --obj->value[2] == 0 && ch->in_room != NULL )
		{
		    --ch->in_room->light;
		    act( "$p goes out.", ch, obj, NULL, TO_ROOM );
		    act( "$p flickers and goes out.", ch, obj, NULL, TO_CHAR );
		    extract_obj( obj );
		}
	 	else if ( obj->value[2] <= 5 && ch->in_room != NULL)
		    act("$p flickers.",ch,obj,NULL,TO_CHAR);
	    }

	    if (IS_IMMORTAL(ch))
		ch->timer = 0;

	    if ( ++ch->timer >= 12 )
	    {
		if ( ch->was_in_room == NULL && ch->in_room != NULL )
		{
		    ch->was_in_room = ch->in_room;
		    if ( ch->fighting != NULL )
			stop_fighting( ch, TRUE );
		    act( "$n disappears into the void.",
			ch, NULL, NULL, TO_ROOM );
		    send_to_char( "You disappear into the void.\n\r", ch );
		    if (ch->level > 1)
		        save_char_obj( ch );
		    char_from_room( ch );
		    char_to_room( ch, get_room_index( ROOM_VNUM_LIMBO ) );
		}
	    }

	    gain_condition( ch, COND_DRUNK,  -1 );
	    gain_condition( ch, COND_FULL, ch->size > SIZE_MEDIUM ? -4 : -2 );
	    gain_condition( ch, COND_THIRST, -1 );
	    gain_condition( ch, COND_HUNGER, ch->size > SIZE_MEDIUM ? -2 : -1);
	}

	for ( paf = ch->affected; paf != NULL; paf = paf_next )
	{
	    paf_next	= paf->next;
	    if ( paf->duration > 0 )
	    {
		paf->duration--;
		if (number_range(0,4) == 0 && paf->level > 0)
		  paf->level--;  /* spell strength fades with time */
            }
	    else if ( paf->duration < 0 )
		;
	    else
	    {
		if ( paf_next == NULL
		||   paf_next->type != paf->type
		||   paf_next->duration > 0 )
		{
		    if ( paf->type > 0 && skill_table[paf->type].msg_off )
		    {
			send_to_char( skill_table[paf->type].msg_off, ch );
			send_to_char( "\n\r", ch );
		    }
		}
	  
		affect_remove( ch, paf );
	    }
	}

	/*
	 * Careful with the damages here,
	 *   MUST NOT refer to ch after damage taken,
	 *   as it may be lethal damage (on NPC).
	 */

        if (is_affected(ch, gsn_plague) && ch != NULL)
        {
            AFFECT_DATA *af, plague;
            CHAR_DATA *vch;
            int dam;

	    if (ch->in_room == NULL)
		continue;
            
	    act("$n writhes in agony as plague sores erupt from $s skin.",
		ch,NULL,NULL,TO_ROOM);
	    send_to_char("You writhe in agony from the plague.\n\r",ch);
            for ( af = ch->affected; af != NULL; af = af->next )
            {
            	if (af->type == gsn_plague)
                    break;
            }
        
            if (af == NULL)
            {
            	REMOVE_BIT(ch->affected_by,AFF_PLAGUE);
            	continue;
            }
        
            if (af->level == 1)
            	continue;
        
	    plague.where		= TO_AFFECTS;
            plague.type 		= gsn_plague;
            plague.level 		= af->level - 1; 
            plague.duration 	= number_range(1,2 * plague.level);
            plague.location		= APPLY_STR;
            plague.modifier 	= -5;
            plague.bitvector 	= AFF_PLAGUE;
        
            for ( vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
            {
                if (!saves_spell(plague.level - 2,vch,DAM_DISEASE) 
		&&  !IS_IMMORTAL(vch)
            	&&  !IS_AFFECTED(vch,AFF_PLAGUE) && number_bits(4) == 0)
            	{
            	    send_to_char("You feel hot and feverish.\n\r",vch);
            	    act("$n shivers and looks very ill.",vch,NULL,NULL,TO_ROOM);
            	    affect_join(vch,&plague);
            	}
            }

	    dam = UMIN(ch->level,af->level/5+1);
	    ch->mana -= dam;
	    ch->move -= dam;
	    damage( ch, ch, dam, gsn_plague,DAM_DISEASE,FALSE);
        }
	else if ( IS_AFFECTED(ch, AFF_POISON) && ch != NULL
	     &&   !IS_AFFECTED(ch,AFF_SLOW))

	{
	    AFFECT_DATA *poison;

	    poison = affect_find(ch->affected,gsn_poison);

	    if (poison != NULL)
	    {
	        act( "$n shivers and suffers.", ch, NULL, NULL, TO_ROOM );
	        send_to_char( "You shiver and suffer.\n\r", ch );
	        damage(ch,ch,poison->level/10 + 1,gsn_poison,
		    DAM_POISON,FALSE);
	    }
	}

	else if ( ch->position == POS_INCAP && number_range(0,1) == 0)
	{
	    damage( ch, ch, 1, TYPE_UNDEFINED, DAM_NONE,FALSE);
	}
	else if ( ch->position == POS_MORTAL )
	{
	    damage( ch, ch, 1, TYPE_UNDEFINED, DAM_NONE,FALSE);
	}
    }

    /*
     * Autosave and autoquit.
     * Check that these chars still exist.
     */
    for ( ch = char_list; ch != NULL; ch = ch_next )
    {
        ch_next = ch->next;

	if (ch->desc != NULL && ch->desc->descriptor % 30 == save_number)
	{
	    save_char_obj(ch);
	}

        if (ch == ch_quit)
	{
            do_function(ch, &do_quit, "" );
	}
    }

    return;
}
예제 #11
0
/*
 * Update all chars, including mobs.
*/
void char_update (void)
{
    CHAR_DATA *ch = NULL;
    CHAR_DATA *ch_next;
    CHAR_DATA *ch_quit;

    ch_quit = NULL;

    /* update save counter */
    save_number++;

    if (save_number > 29)
        save_number = 0;

    for (ch = char_list; ch != NULL; ch = ch_next)
    {
        AFFECT_DATA *paf;
        AFFECT_DATA *paf_next;

        ch_next = ch->next;

    if(!ch->infight)
{
            ch->hit = ch->max_hit;
            ch->mana = ch->max_mana;
            ch->move = ch->max_move;
            update_pos (ch);
}
        if (ch->timer > 30)
            ch_quit = ch;

        if (ch->position == POS_STUNNED)
            update_pos (ch);

        if (!IS_NPC (ch) && ch->level < LEVEL_IMMORTAL)
        {

            if (IS_IMMORTAL (ch))
                ch->timer = 0;

            if (++ch->timer >= 12)
            {
                if (ch->was_in_room == NULL && ch->in_room != NULL)
                {
                    ch->was_in_room = ch->in_room;
                    act ("$n disappears into the void.",
                         ch, NULL, NULL, TO_ROOM);
                    send_to_char ("You disappear into the void.\n\r", ch);
                    if (ch->level > 1)
                        save_char_obj (ch);
                    char_from_room (ch);
                    char_to_room (ch, get_room_index (2));
                }
            }

            gain_condition (ch, COND_DRUNK, -1);
            gain_condition (ch, COND_FULL, ch->size > SIZE_MEDIUM ? -4 : -2);
            gain_condition (ch, COND_THIRST, -1);
            gain_condition (ch, COND_HUNGER,
                            ch->size > SIZE_MEDIUM ? -2 : -1);
        }

        for (paf = ch->affected; paf != NULL; paf = paf_next)
        {
            paf_next = paf->next;
            if (paf->duration > 0)
            {
                paf->duration--;
                if (number_range (0, 4) == 0 && paf->level > 0)
                    paf->level--;    /* spell strength fades with time */
            }
            else if (paf->duration < 0);
            else
            {
                if (paf_next == NULL
                    || paf_next->type != paf->type || paf_next->duration > 0)
                {
                    if (paf->type > 0 && skill_table[paf->type].msg_off)
                    {
                        send_to_char (skill_table[paf->type].msg_off, ch);
                        send_to_char ("\n\r", ch);
                    }
                }

                affect_remove (ch, paf);
            }
        }

        /*
         * Careful with the damages here,
         *   MUST NOT refer to ch after damage taken,
         *   as it may be lethal damage (on NPC).
         */

        if (ch->position == POS_INCAP && number_range (0, 1) == 0)
        {
            damage (ch, ch, 1, TYPE_UNDEFINED, ELE_NON, FALSE);
        }
        else if (ch->position == POS_MORTAL)
        {
            damage (ch, ch, 1, TYPE_UNDEFINED, ELE_NON, FALSE);
        }
    }

    /*
     * Autosave and autoquit.
     * Check that these chars still exist.
     */
    for (ch = char_list; ch != NULL; ch = ch_next)
    {
    	/*
    	 * Edwin's fix for possible pet-induced problem
    	 * JR -- 10/15/00
    	 */
    	if (!IS_VALID(ch))
    	{
        	bug("update_char: Trying to work with an invalidated character.\n",0); 
        	break;
     	}

        ch_next = ch->next;

        if (ch->desc != NULL && ch->desc->descriptor % 30 == save_number)
        {
            save_char_obj (ch);
        }

        if (ch == ch_quit)
        {
            do_function (ch, &do_quit, "");
        }
    }

    return;
}