void set_abstinent(CHAR_DATA *ch) { AFFECT_DATA af; int duration = pc_duration(ch, 2, MAX(0, GET_DRUNK_STATE(ch) - CHAR_DRUNKED), 4, 2, 5); if (can_use_feat(ch, DRUNKARD_FEAT)) duration /= 2; af.type = SPELL_ABSTINENT; af.bitvector = AFF_ABSTINENT; af.duration = duration; af.location = APPLY_AC; af.modifier = 20; affect_join(ch, &af, 0,0,0,0); af.location = APPLY_HITROLL; af.modifier = -2; affect_join(ch, &af, 0,0,0,0); af.location = APPLY_DAMROLL; af.modifier = -2; affect_join(ch, &af, 0,0,0,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); }
void check_berserk(CHAR_DATA * ch) { AFFECT_DATA af; struct timed_type timed; int prob; if (affected_by_spell(ch, SPELL_BERSERK) && (GET_HIT(ch) > GET_REAL_MAX_HIT(ch) / 2)) { affect_from_char(ch, SPELL_BERSERK); send_to_char("Предсмертное исступление оставило Вас.\r\n", ch); } //!IS_NPC(ch) && if (can_use_feat(ch, BERSERK_FEAT) && ch->get_fighting() && !timed_by_feat(ch, BERSERK_FEAT) && !AFF_FLAGGED(ch, AFF_BERSERK) && (GET_HIT(ch) < GET_REAL_MAX_HIT(ch) / 4)) { // if (!IS_NPC(ch)) { //Gorrah: вроде бы у мобов скиллы тикают так же, так что глюков быть не должно timed.skill = BERSERK_FEAT; timed.time = 4; timed_feat_to_char(ch, &timed); // } af.type = SPELL_BERSERK; af.duration = pc_duration(ch, 1, 60, 30, 0, 0); af.modifier = 0; af.location = APPLY_NONE; af.battleflag = 0; prob = IS_NPC(ch) ? 601 : (751 - GET_LEVEL(ch) * 5); if (number(1, 1000) < prob) { af.bitvector = AFF_BERSERK; act("Вас обуяла предсмертная ярость!", FALSE, ch, 0, 0, TO_CHAR); act("$n0 исступленно взвыл$g и бросил$u на противника!", FALSE, ch, 0, 0, TO_ROOM); } else { af.bitvector = 0; act("Вы истошно завопили, пытаясь напугать противника. Без толку.", FALSE, ch, 0, 0, TO_CHAR); act("$n0 истошно завопил$g, пытаясь напугать противника. Забавно...", FALSE, ch, 0, 0, TO_ROOM); } affect_join(ch, &af, TRUE, FALSE, TRUE, FALSE); } }
static void spreadInfection(CharData *theInfected) { CharData *theVictim = world[theInfected->in_room].people; struct affected_type af; if( !CONFIG_PLAGUE_IS_CONTAGIOUS ) return; if( theVictim ){ if( !IS_AFFECTED(theVictim, AFF_PLAGUE) ){ af.type = SPELL_PLAGUE; af.duration = 48 TICKS; af.modifier = -2; af.location = APPLY_STR; af.bitvector = AFF_PLAGUE; affect_join( theVictim, &af, 0, 0, 0, 0 ); mudlog( BRF, LVL_DEITY, TRUE, "(INFECTED) %s with the plague.", GET_NAME(theVictim)); } } }
void trap_sleep(struct char_data *v) { struct affected_type af; if (!saves_spell(v, SAVING_SPELL)) { af.type = SPELL_SLEEP; af.duration = 12; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_SLEEP; affect_join(v, &af, FALSE, FALSE); if (GET_POS(v) > POSITION_SLEEPING) { act("You feel very sleepy ..... zzzzzz", FALSE, v, 0, 0, TO_CHAR); act("$n goes to sleep.", TRUE, v, 0, 0, TO_ROOM); GET_POS(v) = POSITION_SLEEPING; } } else { send_to_char("You feel sleepy,but you recover\n\r", v); } }
void poison_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; poison_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 poisoning */ if (!saves_spell(level / 4 + dam / 20,victim,DAM_POISON)) { AFFECT_DATA af; send_to_char("You feel poison coursing through your veins.\n\r", victim); act("$n looks very ill.",victim,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = gsn_poison; af.level = level; af.duration = level / 2; af.location = APPLY_STR; af.modifier = -1; af.bitvector = AFF_POISON; affect_join( victim, &af ); } /* equipment */ for (obj = victim->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; poison_effect(obj,level,dam,TARGET_OBJ); } return; } if (target == TARGET_OBJ) /* do some poisoning */ { OBJ_DATA *obj = (OBJ_DATA *) vo; int chance = level / 4 + dam / 10; if (IS_OBJ_STAT(obj,ITEM_BURN_PROOF) || IS_OBJ_STAT(obj,ITEM_BLESS) || number_range(0,4) == 0) return; if (chance > 25) chance = (chance - 25) / 2 + 25; if (chance > 50) chance = (chance - 50) / 2 + 50; chance -= obj->level * 2; switch (obj->item_type) { default: return; case ITEM_FOOD: break; case ITEM_DRINK_CON: if (obj->value[0] == obj->value[1]) return; break; } chance = URANGE(5,chance,95); if (number_percent() > chance) return; obj->value[3] = 1; return; } }
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; } }
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; }
void mag_affects(int level, struct char_data *ch, struct char_data *victim, int spellnum, int savetype) { struct affected_type af[MAX_SPELL_AFFECTS]; bool accum_affect = FALSE, accum_duration = FALSE; const char *to_vict = NULL, *to_room = NULL; int i; if (victim == NULL || ch == NULL) return; for (i = 0; i < MAX_SPELL_AFFECTS; i++) { af[i].type = spellnum; af[i].bitvector = 0; af[i].modifier = 0; af[i].location = APPLY_NONE; } switch (spellnum) { case SPELL_CHILL_TOUCH: af[0].location = APPLY_STR; if (mag_savingthrow(victim, savetype, 0)) af[0].duration = 1; else af[0].duration = 4; af[0].modifier = -1; accum_duration = TRUE; to_vict = "You feel your strength wither!"; break; case SPELL_ARMOR: af[0].location = APPLY_AC; af[0].modifier = -20; af[0].duration = 24; accum_duration = TRUE; to_vict = "You feel someone protecting you."; break; case SPELL_BLESS: af[0].location = APPLY_HITROLL; af[0].modifier = 2; af[0].duration = 6; af[1].location = APPLY_SAVING_SPELL; af[1].modifier = -1; af[1].duration = 6; accum_duration = TRUE; to_vict = "You feel righteous."; break; case SPELL_BLINDNESS: if (MOB_FLAGGED(victim,MOB_NOBLIND) || mag_savingthrow(victim, savetype, 0)) { send_to_char(ch, "You fail.\r\n"); return; } af[0].location = APPLY_HITROLL; af[0].modifier = -4; af[0].duration = 2; af[0].bitvector = AFF_BLIND; af[1].location = APPLY_AC; af[1].modifier = 40; af[1].duration = 2; af[1].bitvector = AFF_BLIND; to_room = "$n seems to be blinded!"; to_vict = "You have been blinded!"; break; case SPELL_CURSE: if (mag_savingthrow(victim, savetype, 0)) { send_to_char(ch, "%s", NOEFFECT); return; } af[0].location = APPLY_HITROLL; af[0].duration = 1 + (GET_LEVEL(ch) / 2); af[0].modifier = -1; af[0].bitvector = AFF_CURSE; af[1].location = APPLY_DAMROLL; af[1].duration = 1 + (GET_LEVEL(ch) / 2); af[1].modifier = -1; af[1].bitvector = AFF_CURSE; accum_duration = TRUE; accum_affect = TRUE; to_room = "$n briefly glows red!"; to_vict = "You feel very uncomfortable."; break; case SPELL_DETECT_ALIGN: af[0].duration = 12 + level; af[0].bitvector = AFF_DETECT_ALIGN; accum_duration = TRUE; to_vict = "Your eyes tingle."; break; case SPELL_DETECT_INVIS: af[0].duration = 12 + level; af[0].bitvector = AFF_DETECT_INVIS; accum_duration = TRUE; to_vict = "Your eyes tingle."; break; case SPELL_DETECT_MAGIC: af[0].duration = 12 + level; af[0].bitvector = AFF_DETECT_MAGIC; accum_duration = TRUE; to_vict = "Your eyes tingle."; break; case SPELL_INFRAVISION: af[0].duration = 12 + level; af[0].bitvector = AFF_INFRAVISION; accum_duration = TRUE; to_vict = "Your eyes glow red."; to_room = "$n's eyes glow red."; break; case SPELL_INVISIBLE: if (!victim) victim = ch; af[0].duration = 12 + (GET_LEVEL(ch) / 4); af[0].modifier = -40; af[0].location = APPLY_AC; af[0].bitvector = AFF_INVISIBLE; accum_duration = TRUE; to_vict = "You vanish."; to_room = "$n slowly fades out of existence."; break; case SPELL_POISON: if (mag_savingthrow(victim, savetype, 0)) { send_to_char(ch, "%s", NOEFFECT); return; } af[0].location = APPLY_STR; af[0].duration = GET_LEVEL(ch); af[0].modifier = -2; af[0].bitvector = AFF_POISON; to_vict = "You feel very sick."; to_room = "$n gets violently ill!"; break; case SPELL_PROT_FROM_EVIL: af[0].duration = 24; af[0].bitvector = AFF_PROTECT_EVIL; accum_duration = TRUE; to_vict = "You feel invulnerable!"; break; case SPELL_SANCTUARY: af[0].duration = 4; af[0].bitvector = AFF_SANCTUARY; accum_duration = TRUE; to_vict = "A white aura momentarily surrounds you."; to_room = "$n is surrounded by a white aura."; break; case SPELL_SLEEP: if (!pk_allowed && !IS_NPC(ch) && !IS_NPC(victim)) return; if (MOB_FLAGGED(victim, MOB_NOSLEEP)) return; if (mag_savingthrow(victim, savetype, 0)) return; af[0].duration = 4 + (GET_LEVEL(ch) / 4); af[0].bitvector = AFF_SLEEP; if (GET_POS(victim) > POS_SLEEPING) { send_to_char(victim, "You feel very sleepy... Zzzz......\r\n"); act("$n goes to sleep.", TRUE, victim, 0, 0, TO_ROOM); GET_POS(victim) = POS_SLEEPING; } break; case SPELL_STRENGTH: if (GET_ADD(victim) == 100) return; af[0].location = APPLY_STR; af[0].duration = (GET_LEVEL(ch) / 2) + 4; af[0].modifier = 1 + (level > 18); accum_duration = TRUE; accum_affect = TRUE; to_vict = "You feel stronger!"; break; case SPELL_SENSE_LIFE: to_vict = "Your feel your awareness improve."; af[0].duration = GET_LEVEL(ch); af[0].bitvector = AFF_SENSE_LIFE; accum_duration = TRUE; break; case SPELL_WATERWALK: af[0].duration = 24; af[0].bitvector = AFF_WATERWALK; accum_duration = TRUE; to_vict = "You feel webbing between your toes."; break; } /* * If this is a mob that has this affect set in its mob file, do not * perform the affect. This prevents people from un-sancting mobs * by sancting them and waiting for it to fade, for example. */ if (IS_NPC(victim) && !affected_by_spell(victim, spellnum)) for (i = 0; i < MAX_SPELL_AFFECTS; i++) if (AFF_FLAGGED(victim, af[i].bitvector)) { send_to_char(ch, "%s", NOEFFECT); return; } /* * If the victim is already affected by this spell, and the spell does * not have an accumulative effect, then fail the spell. */ if (affected_by_spell(victim,spellnum) && !(accum_duration||accum_affect)) { send_to_char(ch, "%s", NOEFFECT); return; } for (i = 0; i < MAX_SPELL_AFFECTS; i++) if (af[i].bitvector || (af[i].location != APPLY_NONE)) affect_join(victim, af+i, accum_duration, FALSE, accum_affect, FALSE); if (to_vict != NULL) act(to_vict, FALSE, victim, 0, ch, TO_CHAR); if (to_room != NULL) act(to_room, TRUE, victim, 0, ch, TO_ROOM); }
void Character::update() { AFFECT_DATA *paf; AFFECT_DATA *paf_next; if ( this->desc && this->desc->connected == CON_PLAYING ) send_to_char("\n\r",this); if ( this->position >= POS_STUNNED ) { if ( this->hit < this->max_hit ) this->hit += this->hit_gain(); else this->hit = this->max_hit; if ( this->mana < this->max_mana ) this->mana += this->mana_gain(); else this->mana = this->max_mana; if ( this->move < this->max_move ) this->move += this->move_gain(); else this->move = this->max_move; } if ( this->position == POS_STUNNED ) update_pos( this ); for ( paf = this->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, this ); send_to_char( "\n\r", this ); } } affect_remove( this, 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(this, gsn_plague) && this != NULL) { if (this->in_room == NULL) return; ::act("$n writhes in agony as plague sores erupt from $s skin.", this,NULL,NULL,TO_ROOM); send_to_char("You writhe in agony from the plague.\n\r",this); AFFECT_DATA *af; for ( af = this->affected; af != NULL; af = af->next ) { if (af->type == gsn_plague) break; } if (af == NULL) { REMOVE_BIT(this->affected_by,AFF_PLAGUE); return; } if (af->level == 1) return; AFFECT_DATA plague; 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 ( Character* vch = this->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); } } int dam = UMIN(this->level,af->level/5+1); this->mana -= dam; this->move -= dam; damage_old( this, this, dam, gsn_plague,DAM_DISEASE,FALSE); } else if ( IS_AFFECTED(this, AFF_POISON) && this != NULL && !IS_AFFECTED(this,AFF_SLOW)) { AFFECT_DATA *poison; poison = affect_find(this->affected,gsn_poison); if (poison != NULL) { ::act( "$n shivers and suffers.", this, NULL, NULL, TO_ROOM ); send_to_char( "You shiver and suffer.\n\r", this ); damage_old(this,this,poison->level/10 + 1,gsn_poison, DAM_POISON,FALSE); } } else if ( this->position == POS_INCAP && number_range(0,1) == 0) { ::damage( this, this, 1, TYPE_UNDEFINED, DAM_NONE,FALSE); } else if ( this->position == POS_MORTAL ) { ::damage( this, this, 1, TYPE_UNDEFINED, DAM_NONE,FALSE); } }
int mag_affect_char(struct spell_info_type *sinfo, int affect_flag, struct char_data *caster, struct char_data *vict, int level) { struct affected_type af; int i; int spell = 0; int unaffect = 0; int circle = (level + 4) / 5; /* innate */ if (level == -1) { SET_BIT(AFF_FLAGS(vict), affect_flag); return 1; } if (sinfo->unaffect) { spell = spells[find_spell_num(sinfo->unaffect)].spellindex; unaffect = 1; } if (!unaffect) { af.type = sinfo->spellindex; af.bitvector = sinfo->spell_plr_bit; af.bitvector2 = sinfo->spell_plr_bit2; af.bitvector3 = sinfo->spell_plr_bit3; if (sinfo->spell_duration) af.duration = sinfo->spell_duration * 12; else af.duration = (SECS_PER_MUD_HOUR * level) / 15; /* level/3 mud hours duration */ af.duration = modBySpecialization(caster, sinfo, af.duration); gain_exp(caster, af.duration * 2); if (strcmp(sinfo->command, "stoneskin") == 0) af.duration = level * 5; for (i = 0; i < NUM_MODIFY; i++) { af.modifier[i] = 0; af.location[i] = 0; } for (i = 0; i < NUM_MODIFY; i++) { if (sinfo->plr_aff[i].location) { if (strcmp(sinfo->command, "vitality") == 0 || strcmp(sinfo->command, "vigorize") == 0) af.modifier[i] = (sinfo->plr_aff[i].modifier * level); else if (strcmp(sinfo->command, "barkskin") == 0) { af.modifier[i] = (sinfo->plr_aff[i].modifier - (3.5 * circle)); } else af.modifier[i] = sinfo->plr_aff[i].modifier; af.location[i] = sinfo->plr_aff[i].location; } } if (IS_NPC(vict) && IS_AFFECTED(vict, sinfo->spell_plr_bit) && IS_AFFECTED2(vict, sinfo->spell_plr_bit2) && IS_AFFECTED3(vict, sinfo->spell_plr_bit3) && !affected_by_spell(vict, sinfo->spellindex)) return 0; if (affected_by_spell(vict, sinfo->spellindex) && !(sinfo->accum_duration || sinfo->accum_affect)) return 0; affect_join(vict, &af, sinfo->accum_duration, sinfo->avg_duration, sinfo->accum_affect, sinfo->avg_affect); } else { if (affected_by_spell(vict, sinfo->spellindex) && !(sinfo->accum_duration || sinfo->accum_affect)) return 0; affect_from_char(vict, spell); } return 1; }
void affect_from_char_II(struct char_data * ch, int skill, int type, int action) { struct affected_type *aff, *next; struct affected_type *temp; struct affected_type af[3]; int i, k; bool accum_affect = FALSE, accum_duration = FALSE; for (aff = ch->affected; aff; aff = next) { next = aff->next; if (aff->type == type) { affect_modify(ch, aff->location, aff->modifier, aff->bitvector, FALSE); REMOVE_FROM_LIST(aff, ch->affected, next); free(aff); affect_total(ch); } } if (action == 2) { switch (skill) { case SPELL_POLYMORPH: if (PLR_FLAGGED(ch, PLR_RABBIT)){ REMOVE_BIT(PLR_FLAGS(ch), PLR_RABBIT); REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF); send_to_char("You feel yourself growing, and your ears shrinking. You no longer feel like a rabbit.\r\n", ch); act("$n's body grows, $s ears shrinking. $n no longer looks like a rabbit.\r\n", 0, ch, 0, 0, TO_ROOM); } if (PLR_FLAGGED(ch, PLR_BIRD)) { REMOVE_BIT(PLR_FLAGS(ch), PLR_BIRD); REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF); send_to_char("You feel yourself growing and your feathers falling away. You no longer feel like a bird.\r\n", ch); act("$n's body grows, $s feathers falling away as it expands. $n no longer looks like a bird.\r\n", 0, ch, 0, 0, TO_ROOM); } if (PLR_FLAGGED(ch, PLR_WOLF)) { REMOVE_BIT(PLR_FLAGS(ch), PLR_WOLF); REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF); send_to_char("You feel your your fur shed and your teeth shrink. You no longer feel like a wolf.\r\n", ch); act("$n's teeth shrink, $s fur shedding. $n no longer looks like a wolf.\r\n", 0, ch, 0, 0, TO_ROOM); } if (PLR_FLAGGED(ch, PLR_BEAR)) { REMOVE_BIT(PLR_FLAGS(ch), PLR_BEAR); REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF); send_to_char("Your claws shrink as does the rest of your body. You no longer feel like a bear.\r\n", ch); act("$n's claws shrink as does the rest of $s body. $n no longer looks like a bear.\r\n", 0, ch, 0, 0, TO_ROOM); } if (PLR_FLAGGED(ch, PLR_CAT)){ REMOVE_BIT(PLR_FLAGS(ch), PLR_CAT); REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF); send_to_char("You feel your body growing, and your fur shedding. You no longer feel like a cat.\r\n", ch); act("$n's body slowly grows, $s fur shedding. $n no longer looks like a cat.\r\n", 0, ch, 0, 0, TO_ROOM); } for (k = 0; k < NUM_WEARS; k++) if (GET_EQ(ch, k)){ GET_OBJ_DISGUISE(GET_EQ(ch, k)) = 0; } if (affected_by_spell(ch, SPELL_FLIGHT)) affect_from_char_II(ch, SPELL_FLIGHT, SPELL_FLIGHT, 1); if (affected_by_spell(ch, SPELL_HASTE)) affect_from_char_II(ch, SPELL_HASTE, SPELL_HASTE, 1); break; case SKILL_STANCE: if (!AFF_FLAGGED(ch, AFF_TIRED)) { for (i = 0; i < 3; i++) { af[0].type = SPELL_DONTUSEME; af[0].location = APPLY_HITROLL; af[0].modifier = 2; af[0].duration = 7; af[0].bitvector = AFF_STANCE; af[1].type = SPELL_DONTUSEME; af[1].location = APPLY_AC; af[1].modifier = -50; af[1].duration = 7; af[1].bitvector = AFF_STANCE; af[2].type = SPELL_DONTUSEME; af[2].location = APPLY_STR; af[2].modifier = 2; af[2].duration = 7; af[2].bitvector = AFF_STANCE; if (af[i].bitvector || (af[i].location != APPLY_NONE)) { affect_join(ch, af+i, accum_duration, FALSE, accum_affect, FALSE); } } } break; default: break; } } }
void perform_smoke(struct creature *ch, int type) { const char *to_vict = NULL; struct affected_type af; int hp_mod = 0, mana_mod = 0, move_mod = 0, spell = 0; uint8_t lev = 0; int accum_dur = 0, accum_affect = 0; init_affect(&af); af.type = SMOKE_EFFECTS; af.level = 30; af.owner = GET_IDNUM(ch); switch (type) { case SMOKE_DIRTWEED: to_vict = "Your head hurts."; af.duration = 3; af.modifier = -2; af.location = APPLY_INT; af.bitvector = AFF_CONFUSION; af.aff_index = 1; accum_dur = 1; accum_affect = 1; move_mod = -number(3, 10); mana_mod = -number(1, 2); break; case SMOKE_DESERTWEED: af.location = APPLY_MOVE; af.duration = 4; af.modifier = 10; mana_mod = dice(1, 4); move_mod = dice(3, 4); break; case SMOKE_INDICA: to_vict = "Your mind is elevated to another plane."; af.location = APPLY_WIS; af.duration = 5; af.modifier = number(1, 2); mana_mod = dice(6, 4); move_mod = -number(1, 3); break; case SMOKE_UNHOLY_REEFER: af.location = APPLY_WIS; af.duration = 5; af.modifier = number(0, 2); mana_mod = number(1, 4); move_mod = -number(1, 3); spell = SPELL_ESSENCE_OF_EVIL; lev = 20; break; case SMOKE_MARIJUANA: to_vict = "You feel stoned."; af.location = APPLY_INT; af.duration = 3; af.modifier = -1; mana_mod = dice(4, 4); break; case SMOKE_TOBACCO: af.location = APPLY_MOVE; af.duration = 3; af.modifier = -number(10, 20); accum_dur = 1; mana_mod = dice(3, 3); break; case SMOKE_HEMLOCK: to_vict = "The smoke burns your lungs!"; af.location = APPLY_HIT; af.duration = number(3, 6); af.modifier = -number(30, 60); accum_affect = 1; hp_mod = -number(10, 16); mana_mod = -10; move_mod = -10; spell = SPELL_POISON; lev = LVL_AMBASSADOR; break; case SMOKE_PEYOTE: to_vict = "You feel a strange sensation."; spell = SPELL_ASTRAL_SPELL; lev = LVL_GRIMP; af.location = APPLY_MANA; af.modifier = number(10, 20); af.duration = number(1, 3); move_mod = number(6, 12); break; case SMOKE_HOMEGROWN: to_vict = "There's no place like home..."; spell = SPELL_WORD_OF_RECALL; lev = number(30, 60); mana_mod = number(20, 40); move_mod = number(2, 10); break; default: af.type = 0; break; } if (to_vict) act(to_vict, false, ch, NULL, NULL, TO_CHAR); GET_HIT(ch) = MIN(MAX(GET_HIT(ch) + hp_mod, 0), GET_MAX_HIT(ch)); GET_MANA(ch) = MIN(MAX(GET_MANA(ch) + mana_mod, 0), GET_MAX_MANA(ch)); GET_MOVE(ch) = MIN(MAX(GET_MOVE(ch) + move_mod, 0), GET_MAX_MOVE(ch)); if (af.type && (!affected_by_spell(ch, af.type) || accum_affect || accum_dur)) affect_join(ch, &af, accum_dur, true, accum_affect, true); if (spell && lev) call_magic(ch, ch, NULL, NULL, spell, (int)lev, CAST_CHEM); WAIT_STATE(ch, 6); }
/* * 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; }
void do_chaos( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; AFFECT_DATA af; int chaos, dam; char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; argument = one_argument( argument, arg ); if (IS_NPC(ch)) return; if (!IS_CLASS(ch, CLASS_WIZARD)) { send_to_char("Huh?\n\r",ch); return; } if (ch->pcdata->stats[WL_SPELLS] < 6) { send_to_char("Huh?\n\r",ch); return; } if ( arg[0] == '\0') { send_to_char( "#RCast chaos orb on whom?\n\r", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They are not here.\n\r", ch ); return; } if (is_safe(ch, victim)) { stc("You cannot attack them.\n\r",ch); return; } if (ch->mana < 5000) { stc("You do not ave the required 5000 mana.\n\r",ch); return; } chaos = number_range(1, 6); act("#r$n#0 begins chanting dark words, summoning forth a sphere of #rc#lh#pa#go#cs#0 to hurl at #r$N!#n", ch, NULL, victim, TO_NOTVICT); sprintf( buf, "#0You summon forth a perfect sphere of #rc#lh#pa#go#cs#0 and hurl it at #r$N!#n\n\r"); act(buf, ch, NULL, victim, TO_CHAR); sprintf( buf, "#r$n#0 summons forth a perfect sphere of #rc#lh#pa#go#cs#0 and hurls it at you!#n\n\r"); act(buf, ch, NULL, victim, TO_VICT); if (chaos == 1 || chaos == 6) { stc("The sphere explodes in a shower of #Ggreen bubbles#n.\n\r",victim); stc("Your sphere explodes in a shower of #Ggreen bubbles#n.\n\r",ch); if ( IS_AFFECTED(victim, AFF_POISON)) return; af.type = gsn_poison; af.duration = chaos * 10; af.location = APPLY_STR; af.modifier = 0 - number_range(1,3); af.bitvector = AFF_POISON; affect_join( victim, &af ); WAIT_STATE(victim, number_range(5, 20)); send_to_char( "#GYou are poisoned!#n\n\r", victim ); } else if (chaos == 2 || chaos == 7 ) { stc("The sphere explodes, forming a #yyellow haze#n.\n\r",victim); stc("Your sphere explodes, forming a #yyellow haze#n.\n\r",ch); if ( IS_AFFECTED(victim, AFF_BLIND)) { af.type = gsn_blindness; af.location = APPLY_HITROLL; af.modifier = -4; af.duration = chaos * 10; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); WAIT_STATE(victim, number_range(5, 15)); send_to_char( "#yYou are blinded!#n\n\r", victim ); } else { stc("They are already blinded.\n\r",ch); } } else if (chaos == 3 || chaos == 8) { stc("The sphere explodes in a shower of #Rred flames#n.\n\r",victim); stc("Your sphere explodes in a shower of #Rred flames#n.\n\r",ch); WAIT_STATE(victim, number_range(5, 20)); SET_BIT(victim->affected_by, AFF_FLAMING); } else if (chaos == 4 || chaos == 9) { dam = number_range(3750, 7500); sprintf(buf,"The sphere explodes in a scattering of #Lblue sparks#n. #R[#y%d#R]#n\n\r", dam); stc( buf, victim); sprintf(buf,"Your sphere explodes in a scattering of #Lblue sparks#n. #R[#y%d#R]#n\n\r", dam); stc( buf, ch); WAIT_STATE(victim, number_range(5, 8)); hurt_person(ch, victim, dam); } else if (chaos == 5 ) { stc("The sphere dissipates before it hits you#n.\n\r",victim); stc("Your sphere dissipates shortly after casting#n.\n\r",ch); } one_hit(ch,victim, gsn_wrathofgod,1); one_hit(ch,victim, gsn_wrathofgod,1); WAIT_STATE(ch, 4); ch->mana -= 5000; if (victim->hit < -10) victim->hit = -10; return; }
void race_affects(struct char_data *ch) { int race; struct affected_type af; extern void affect_join(struct char_data *c, struct affected_type *a, bool ad, bool avg, bool mod, bool avgmod); race = GET_RACE(ch); switch(race) { case RACE_HYLAR: case RACE_DAEWAR: case RACE_NEIDAR: af.type = SPELL_INFRAVISION; af.duration = -1; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_INFRAVISION; affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE); if ( GET_SKILL(ch, SKILL_NATURAL_HARDINESS) < 60 ) { SET_SKILL(ch, SKILL_NATURAL_HARDINESS, 60); } break; case RACE_SILVANESTI: case RACE_QUALINESTI: case RACE_KAGONESTI: case RACE_HALFELVEN: case RACE_GNOME: af.type = SPELL_INFRAVISION; af.duration = -1; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_INFRAVISION; affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE); break; case RACE_MINOTAUR: if ( GET_SKILL(ch, SKILL_GORE) < 60 ) { SET_SKILL(ch, SKILL_GORE, 60); } // GET_AC(ch) -= 12; break; case RACE_KENDER: af.type = SPELL_INFRAVISION; af.duration = -1; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_INFRAVISION; affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE); if ( GET_SKILL(ch, SKILL_HIDE) < 60 ) { SET_SKILL(ch, SKILL_HIDE, 60); } if ( GET_SKILL(ch, SKILL_SNEAK) < 60 ) { SET_SKILL(ch, SKILL_SNEAK, 60); } if ( GET_SKILL(ch, SKILL_PICK_LOCK) < 60 ) { SET_SKILL(ch, SKILL_PICK_LOCK, 60); } if ( GET_SKILL(ch, SKILL_STEAL) < 60 ) { SET_SKILL(ch, SKILL_STEAL, 60); } break; default: break; } }
void do_forge(CHAR_DATA * ch, char *argument) { char arg[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH]; OBJ_DATA *obj, *hammer; int wear, lvl; long group1 = ITEM_ANTI_HUMAN + ITEM_ANTI_DROW + ITEM_ANTI_ELF + ITEM_ANTI_ELDER; long group2 = ITEM_ANTI_OGRE + ITEM_ANTI_TROLL + ITEM_ANTI_DEMON + ITEM_ANTI_MINOTAUR; long group3 = ITEM_ANTI_DWARF + ITEM_ANTI_HALFLING + ITEM_ANTI_SHADOW; long group4 = ITEM_ANTI_ILLITHID + ITEM_ANTI_GHOUL; long group5 = ITEM_ANTI_PIXIE; long group6 = ITEM_ANTI_LIZARDMAN; long antirace = 0; wear = 0; if (ch->race != RACE_DWARF) { send_to_char(AT_GREY, "You aren't a dwarf!\n\r", ch); return; } if (argument[0] == '\0') { send_to_char(AT_WHITE, "Syntax: Forge <obj> <race> <lvl>\n\r", ch); send_to_char(AT_WHITE, " obj = ring necklace armor helm\n\r", ch); send_to_char(AT_WHITE, " mask leggings boots gauntlets\n\r", ch); send_to_char(AT_WHITE, " gauntlets armplates shield\n\r", ch); send_to_char(AT_WHITE, " belt bracer anklet weapon\n\r", ch); send_to_char(AT_WHITE, " race= any valid race. HELP FORGE RACES\n\r", ch); send_to_char(AT_WHITE, " to see race groupings.\n\r", ch); sprintf(buf, " lvl = minimum 30, maximum %d.\n\r", ch->level); send_to_char(AT_WHITE, buf, ch); send_to_char(AT_WHITE, " BASE cost to make item is: 100 gold * lvl\n\r", ch); return; } if (ch->in_room->vnum != ROOM_VNUM_SMITHY) { send_to_char(AT_GREY, "You cannot forge equipment here.\n\r", ch); return; } for (hammer = ch->carrying; hammer; hammer = hammer->next) { if (hammer->pIndexData->vnum == OBJ_VNUM_SMITHY_HAMMER && hammer->wear_loc == WEAR_HOLD) break; } if (!hammer) { send_to_char(AT_GREY, "You must hold a smithy hammer to forge something.\n\r", ch); return; } argument = one_argument(argument, arg); argument = one_argument(argument, arg2); if (!str_prefix(arg, "ring")) wear = ITEM_WEAR_FINGER; if (!str_prefix(arg, "necklace")) wear = ITEM_WEAR_NECK; if (!str_prefix(arg, "armor")) wear = ITEM_WEAR_BODY; if (!str_prefix(arg, "helm")) wear = ITEM_WEAR_HEAD; if (!str_prefix(arg, "mask")) wear = ITEM_WEAR_FACE; if (!str_prefix(arg, "leggings")) wear = ITEM_WEAR_LEGS; if (!str_prefix(arg, "boots")) wear = ITEM_WEAR_FEET; if (!str_prefix(arg, "gauntlets")) wear = ITEM_WEAR_HANDS; if (!str_prefix(arg, "armplates")) wear = ITEM_WEAR_ARMS; if (!str_prefix(arg, "shield")) wear = ITEM_WEAR_SHIELD; if (!str_prefix(arg, "belt")) wear = ITEM_WEAR_WAIST; if (!str_prefix(arg, "bracer")) wear = ITEM_WEAR_WRIST; if (!str_prefix(arg, "anklet")) wear = ITEM_WEAR_ANKLE; if (!str_prefix(arg, "weapon")) wear = ITEM_WIELD; if (!str_prefix(arg2, "elf") || !str_prefix(arg2, "drow") || !str_prefix(arg2, "elder") || !str_prefix(arg2, "human")) antirace = group2 + group3 + group4 + group5 + group6; if (!str_prefix(arg2, "ogre") || !str_prefix(arg2, "demon") || !str_prefix(arg2, "troll") || !str_prefix(arg2, "minotaur")) antirace = group1 + group3 + group4 + group5 + group6; if (!str_prefix(arg2, "dwarf") || !str_prefix(arg2, "halfling") || !str_prefix(arg2, "shadow")) antirace = group1 + group2 + group4 + group5 + group6; if (!str_prefix(arg2, "illithid") || !str_prefix(arg2, "ghoul")) antirace = group1 + group2 + group3 + group5 + group6; if (!str_prefix(arg2, "pixie")) antirace = group1 + group2 + group3 + group4 + group6; if (!str_prefix(arg2, "lizardman")) antirace = group1 + group2 + group3 + group4 + group5; if (is_number(argument)) lvl = atoi(argument); else lvl = 0; if (wear && antirace && (lvl < 30 || lvl > ch->level)) { sprintf(buf, "Illegal level. Valid levels are 30 to %d.\n\r", ch->level); send_to_char(AT_GREY, buf, ch); return; } if (wear && antirace == 0) { send_to_char(AT_GREY, "Illegal race. Help RACE for valid race list.\n\r", ch); return; } if (wear) { #ifdef NEW_MONEY if ((ch->money.gold + (ch->money.silver / SILVER_PER_GOLD) + (ch->money.copper / COPPER_PER_GOLD)) < (lvl * 100)) { #else if (ch->gold < lvl * 10000) { #endif send_to_char(AT_GREY, "You do not have enough money to create the base item of this level.\n\r", ch); return; } else if (wear == ITEM_WIELD) obj = create_object(get_obj_index(OBJ_VNUM_TO_FORGE_W), lvl); else obj = create_object(get_obj_index(OBJ_VNUM_TO_FORGE_A), lvl); #ifdef NEW_MONEY obj->cost.silver = obj->cost.copper = 0; obj->cost.gold = lvl * 100; #else obj->cost = lvl * 10000; #endif obj->weight = lvl * 0.15; obj->level = lvl; obj->anti_race_flags = antirace; if (obj->level >= 101) obj->extra_flags += ITEM_NO_DAMAGE; obj->wear_flags += wear; forge_obj(ch, obj); } else do_forge(ch, ""); return; } void do_spit(CHAR_DATA * ch, char *argument) { AFFECT_DATA af; CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; int dam; if (ch->race != RACE_LIZARDMAN) { send_to_char(AT_GREY, "Huh?\n\r", ch); return; } if (ch->race_wait > 0) return; if (!ch->fighting) { send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch); return; } one_argument(argument, arg); victim = ch->fighting; if (arg[0] != '\0') if (!(victim = get_char_room(ch, arg))) { send_to_char(C_DEFAULT, "They aren't here.\n\r", ch); return; } dam = ch->level + number_range(ch->level, ch->level * 4); damage(ch, victim, dam, gsn_spit); ch->race_wait = 36; if (!victim || victim->position == POS_DEAD || !victim->in_room || victim->in_room != ch->in_room) return; if (number_percent() < 25) { int location = number_range(0, 1); switch (location) { case 0: if (victim->race != RACE_ILLITHID) { act(AT_DGREEN, "You spit right in $S eyes!", ch, NULL, victim, TO_CHAR); act(AT_DGREEN, "$n spit into $N's eyes!", ch, NULL, victim, TO_NOTVICT); act(AT_DGREEN, "$n spit into your eyes!", ch, NULL, victim, TO_VICT); if (!IS_AFFECTED(victim, AFF_BLIND)) { send_to_char(AT_WHITE, "You are blinded!", victim); act(AT_WHITE, "$n is blinded!", victim, NULL, NULL, TO_ROOM); af.type = gsn_spit; af.level = ch->level; af.duration = 0; af.location = APPLY_HITROLL; af.modifier = -10; af.bitvector = AFF_BLIND; affect_to_char(victim, &af); af.location = APPLY_AC; af.modifier = 50; affect_to_char(victim, &af); } } break; case 1: act(AT_DGREEN, "You spit right in $S mouth!", ch, NULL, victim, TO_CHAR); act(AT_DGREEN, "$n spit into $N's mouth! Gross!", ch, NULL, victim, TO_NOTVICT); act(AT_DGREEN, "$n spit into your mouth!", ch, NULL, victim, TO_VICT); send_to_char(AT_WHITE, "The acidic spit burns your mouth and throat.\n\r", victim); STUN_CHAR(victim, 2, STUN_MAGIC); break; } } if (!saves_spell(ch->level, victim) && victim->race != RACE_GHOUL) { af.type = gsn_poison; af.level = ch->level; af.duration = 2; af.location = APPLY_STR; af.modifier = -3; af.bitvector = 0; affect_join(victim, &af); } return; }