/* DaleMUD v2.0 Released 2/1994 See license.doc for distribution terms. DaleMUD is based on DIKUMUD */ #include <stdio.h> #include "protos.h" extern struct char_data *character_list; /* struct room_data *real_roomp(int); */ extern int TrapDir[]; void NailThisSucker( struct char_data *ch); void TrapPoison(struct char_data *v, struct obj_data *i); /* move to protos.h later... */ void do_settrap( struct char_data *ch, char *arg, int cmd) { /* parse for directions */ /* trap that affects all directions is an AE trap */ /* parse for type */ /* parse for level */ } int CheckForMoveTrap(struct char_data *ch, int dir) { struct obj_data *i; int trig=FALSE; for (i = real_roomp(ch->in_room)->contents; i; i = i->next_content) { if ((ITEM_TYPE(i) == ITEM_TRAP) && (GET_TRAP_CHARGES(i) > 0)) if ( IS_SET(GET_TRAP_EFF(i), TrapDir[dir]) && IS_SET(GET_TRAP_EFF(i), TRAP_EFF_MOVE) ) return(TriggerTrap(ch, i)); } return(FALSE); } int CheckForInsideTrap(struct char_data *ch, struct obj_data *i) { struct obj_data *t; for (t = i->contains; t; t = t->next_content) { if ((ITEM_TYPE(t) == ITEM_TRAP) && (IS_SET(GET_TRAP_EFF(t),TRAP_EFF_OBJECT)) && (GET_TRAP_CHARGES(t) > 0)) { return(TriggerTrap(ch, t)); } } return(FALSE); } int CheckForAnyTrap(struct char_data *ch, struct obj_data *i) { if ((ITEM_TYPE(i) == ITEM_TRAP) && (GET_TRAP_CHARGES(i) > 0)) return(TriggerTrap(ch, i)); return(FALSE); } int CheckForGetTrap(struct char_data *ch, struct obj_data *i) { if ((ITEM_TYPE(i) == ITEM_TRAP) && (IS_SET(GET_TRAP_EFF(i),TRAP_EFF_OBJECT)) && (GET_TRAP_CHARGES(i) > 0)) { return(TriggerTrap(ch, i)); } return(FALSE); } int TriggerTrap( struct char_data *ch, struct obj_data *i) { int adj, fireperc, roll; struct char_data *v; extern struct dex_app_type dex_app[]; if (ITEM_TYPE(i) == ITEM_TRAP) { if (i->obj_flags.value[TRAP_CHARGES]) { #if 0 /* I did not like this, traps should just go off unless you can */ /* detect and disarm them I disable this stuff */ /* the lower level you are the more likly you are to set the */ /* trap off. */ adj = GET_TRAP_LEV(i) - GetMaxLevel(ch); /* Dex bonus... */ adj -= dex_app[GET_DEX(ch)].reaction * 5; fireperc = 95 + adj; roll = number(1,100); if (roll < fireperc) { /* trap is sprung */ #endif act("You hear a strange noise...", TRUE, ch, 0, 0, TO_ROOM); act("You hear a strange noise...", TRUE, ch, 0, 0, TO_CHAR); GET_TRAP_CHARGES(i) -= 1; /* make sure room fire off works! */ if (IS_SET(GET_TRAP_EFF(i),TRAP_EFF_ROOM)) { for (v = real_roomp(ch->in_room)->people;v;v = v->next_in_room) { FindTrapDamage(v,i); } /* end for */ } /* end is_set */ else { FindTrapDamage(ch,i); } /* end was not fire trap */ return(TRUE); } /* end trap had charges */ return(FALSE); } return(FALSE); } void FindTrapDamage( struct char_data *v, struct obj_data *i) { /* trap types < 0 are special */ if (GET_TRAP_DAM_TYPE(i) >= 0) { TrapDamage(v,GET_TRAP_DAM_TYPE(i),3*GET_TRAP_LEV(i),i); } else { TrapDamage(v, GET_TRAP_DAM_TYPE(i), 0,i); } } void TrapDamage(struct char_data *v, int damtype, int amnt, struct obj_data *t) { char buf[132]; amnt = SkipImmortals(v, amnt,damtype); if (amnt == -1) { return; } if (IS_AFFECTED(v, AFF_SANCTUARY)) amnt = MAX((int)(amnt/2), 0); /* Max 1/2 damage when sanct'd */ amnt = PreProcDam(v, damtype, amnt); if (saves_spell(v, SAVING_PETRI)) amnt = MAX((int)(amnt/2),0); DamageStuff(v, damtype, amnt); amnt=MAX(amnt,0); GET_HIT(v)-=amnt; update_pos(v); TrapDam(v, damtype, amnt, t); InformMess(v); if (GET_POS(v) == POSITION_DEAD) { if (!IS_NPC(v)) { if (real_roomp(v->in_room)->name) sprintf(buf, "%s killed by a trap at %s", GET_NAME(v), real_roomp(v->in_room)->name); log_string(buf); } die(v,NULL); } } void TrapDam(struct char_data *v, int damtype, int amnt, struct obj_data *t) { char desc[20]; char buf[132]; /* easier than dealing with message(ug) */ switch(damtype) { case TRAP_DAM_PIERCE: strcpy(desc,"pierced"); break; case TRAP_DAM_SLASH: strcpy(desc,"sliced"); break; case TRAP_DAM_BLUNT: strcpy(desc,"pounded"); break; case TRAP_DAM_FIRE: strcpy(desc,"seared"); break; case TRAP_DAM_COLD: strcpy(desc, "frozen"); break; case TRAP_DAM_ACID: strcpy(desc, "corroded"); break; case TRAP_DAM_ENERGY: strcpy(desc, "blasted"); break; case TRAP_DAM_SLEEP: strcpy(desc, "knocked out"); break; case TRAP_DAM_TELEPORT: strcpy(desc, "transported"); break; case TRAP_DAM_POISON: strcpy(desc, "poisoned"); break; default: /* need a poison trap! */ strcpy(desc, "blown away"); break; } if ((damtype != TRAP_DAM_TELEPORT) && (damtype != TRAP_DAM_SLEEP) && (damtype != TRAP_DAM_POISON)) { /* check for poison trap here */ if (amnt > 0) { sprintf(buf, "$n is %s by $p!", desc); act(buf,TRUE,v,t,0,TO_ROOM); sprintf(buf, "You are %s by $p!", desc); act(buf,TRUE,v,t,0,TO_CHAR); } else { sprintf(buf, "$n is almost %s by $p!", desc); act(buf,TRUE,v,t,0,TO_ROOM); sprintf(buf, "You are almost %s by $p!", desc); act(buf,TRUE,v,t,0,TO_CHAR); } } if (damtype == TRAP_DAM_TELEPORT) { TrapTeleport(v); } else if (damtype == TRAP_DAM_SLEEP) { TrapSleep(v); } else if (damtype == TRAP_DAM_POISON) { TrapPoison(v,t); } } void TrapTeleport(struct char_data *v) { int to_room,try = 0; extern int top_of_world; /* ref to the top element of world */ struct room_data *room; if (saves_spell(v,SAVING_SPELL)) { send_to_char("You feel strange, but the effect fades.\n\r",v); return; } do { /* do .. while bug fixed, msw */ to_room = number(0, top_of_world); room = real_roomp(to_room); if (room) { if ((IS_SET(room->room_flags, PRIVATE)) || (IS_SET(room->room_flags, TUNNEL)) || (IS_SET(room->room_flags, NO_SUM)) || (IS_SET(room->room_flags, NO_MAGIC)) || !IsOnPmp(to_room)) { room = 0; try++; } } } while (!room && try < 10); if (try >= 10) { send_to_char("The magic fails, you got lucky!\n\r", v); return; } act("$n slowly fade out of existence.", FALSE, v,0,0,TO_ROOM); char_from_room(v); char_to_room(v, to_room); act("$n slowly fade in to existence.", FALSE, v,0,0,TO_ROOM); do_look(v, "", 0); if (IS_SET(real_roomp(to_room)->room_flags, DEATH) && GetMaxLevel(v) < LOW_IMMORTAL) { NailThisSucker(v); } } void TrapSleep(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 TrapPoison(struct char_data *v, struct obj_data *t) { act("You feel sick.",FALSE,v,0,0,TO_CHAR); act("$n looks sick.",TRUE,v,0,0,TO_ROOM); cast_poison(GET_TRAP_LEV(t),v, "", SPELL_TYPE_SPELL, v, 0); } void InformMess( struct char_data *v) { switch (GET_POS(v)) { case POSITION_MORTALLYW: act("$n is mortally wounded, and will die soon, if not aided.", TRUE, v, 0, 0, TO_ROOM); act("You are mortally wounded, and will die soon, if not aided.", FALSE, v, 0, 0, TO_CHAR); break; case POSITION_INCAP: act("$n is incapacitated and will slowly die, if not aided.", TRUE, v, 0, 0, TO_ROOM); act("You are incapacitated and you will slowly die, if not aided.", FALSE, v, 0, 0, TO_CHAR); break; case POSITION_STUNNED: act("$n is stunned, but will probably regain consciousness.", TRUE, v, 0, 0, TO_ROOM); act("You're stunned, but you will probably regain consciousness.", FALSE, v, 0, 0, TO_CHAR); break; case POSITION_DEAD: act("$n is dead! R.I.P.", TRUE, v, 0, 0, TO_ROOM); act("You are dead! Sorry...", FALSE, v, 0, 0, TO_CHAR); break; default: /* >= POSITION SLEEPING */ break; } }