/************************************************************************** * # # # ## # # ### ## ## ### http://www.lyonesse.it * * # # # # # ## # # # # # * * # # # # # ## ## # # ## ## ## # # ## * * # # # # # ## # # # # # # # # # # # * * ### # ## # # ### ## ## ### # # #### ## Ver. 1.0 * * * * -Based on CircleMud & Smaug- Copyright (c) 2001-2002 by Mithrandir * * * * ********************************************************************** * * * * File: obj_trap.c * * * * Trapped items code * * * **************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "handler.h" #include "db.h" #include "constants.h" #include "spells.h" /* ======================================================================= */ int parse_trap_dam( char *damname ) { if (!str_cmp(damname, "sleep")) return (TRAP_DAM_SLEEP); if (!str_cmp(damname, "teleport")) return (TRAP_DAM_TELEPORT); if (!str_cmp(damname, "fire")) return (TRAP_DAM_FIRE); if (!str_cmp(damname, "cold")) return (TRAP_DAM_COLD); if (!str_cmp(damname, "acid")) return (TRAP_DAM_ACID); if (!str_cmp(damname, "energy")) return (TRAP_DAM_ENERGY); if (!str_cmp(damname, "blunt")) return (TRAP_DAM_BLUNT); if (!str_cmp(damname, "pierce")) return (TRAP_DAM_PIERCE); if (!str_cmp(damname, "slash")) return (TRAP_DAM_SLASH); return (TRAP_DAM_NONE); } void trap_damage(CHAR_DATA *ch, OBJ_DATA *obj, OBJ_TRAP_DATA *trap) { CHAR_DATA *wch; int dam = 0, level; act("You hear a strange noise......", FALSE, ch, 0, 0, TO_ROOM); act("You hear a strange noise......", FALSE, ch, 0, 0, TO_CHAR); trap->charges--; level = URANGE(1, GET_OBJ_LEVEL(obj), LVL_IMMORT); switch (trap->dam_type) { case TRAP_DAM_SLEEP: if ( !trap->whole_room ) { if (AFF_FLAGGED(ch, AFF_SLEEP)) return; call_magic(ch, ch, NULL, SPELL_SLEEP, level, CAST_OBJ); } else { for (wch = ch->in_room->people; wch; wch = wch->next_in_room) { if (AFF_FLAGGED(wch, AFF_SLEEP) || IS_IMMORTAL(wch)) continue; call_magic(wch, wch, NULL, SPELL_SLEEP, level, CAST_OBJ); } } return; case TRAP_DAM_FIRE: if ( !trap->whole_room ) { act("A fireball shoots out of $p and hits $n!", FALSE, ch, obj, 0, TO_ROOM); act("A fireball shoots out of $p and hits you!", FALSE, ch, obj, 0, TO_CHAR); } else { act("A fireball shoots out of $p and hits everyone in the room!", FALSE, ch, obj, 0, TO_ROOM); act("A fireball shoots out of $p and hits everyone in the room!", FALSE, ch, obj, 0, TO_CHAR); } dam = level * 4; break; case TRAP_DAM_COLD: if ( !trap->whole_room ) { act("A blast of frost from $p hits $n!", FALSE, ch, obj, 0, TO_ROOM); act("A blast of frost from $p hits you!", FALSE, ch, obj, 0, TO_CHAR); } else { act("A blast of frost from $p fills the room freezing you!", FALSE, ch, obj, 0, TO_ROOM); act("A blast of frost from $p fills the room freezing you!", FALSE, ch, obj, 0, TO_CHAR); } dam = level * 5; break; case TRAP_DAM_ACID: if ( !trap->whole_room ) { act("A blast of acid erupts from $p, burning your skin!", FALSE, ch, obj, 0, TO_CHAR); act("A blast of acid erupts from $p, burning $n's skin!", FALSE, ch, obj, 0, TO_ROOM); } else { act("A blast of acid erupts from $p, burning your skin!", FALSE, ch, obj, 0, TO_ROOM); act("A blast of acid erupts from $p, burning your skin!", FALSE, ch, obj, 0, TO_CHAR); } dam = level * 6; break; case TRAP_DAM_ENERGY: if ( !trap->whole_room ) { act("A pulse of energy from $p zaps $n!", FALSE, ch, obj, 0, TO_ROOM); act("A pulse of energy from $p zaps you!", FALSE, ch, obj, 0, TO_CHAR); } else { act("A pulse of energy from $p zaps you!", FALSE, ch, obj, 0, TO_ROOM); act("A pulse of energy from $p zaps you!", FALSE, ch, obj, 0, TO_CHAR); } dam = level * 3; break; case TRAP_DAM_BLUNT: if ( !trap->whole_room ) { act("$n sets off a trap on $p and is hit by a blunt object!", FALSE, ch, obj, 0, TO_ROOM); act("You are hit by a blunt object from $p!", FALSE, ch, obj, 0, TO_CHAR); } else { act("$n sets off a trap on $p and you are hit by a flying object!", FALSE, ch, obj, 0, TO_ROOM); act("You are hit by a blunt object from $p!", FALSE, ch, obj, 0, TO_CHAR); } dam = (10 * level) + GET_AC(ch); break; case TRAP_DAM_PIERCE: if ( !trap->whole_room ) { act("$n sets of a trap on $p and is pierced in the chest!", FALSE, ch, obj, 0, TO_ROOM); act("You set off a trap on $p and are pierced through the chest!", FALSE, ch, obj, 0, TO_CHAR); } else { act("$n sets off a trap on $p and you are hit by a piercing object!", FALSE, ch, obj, 0, TO_ROOM); act("You set off a trap on $p and are pierced through the chest!", FALSE, ch, obj, 0, TO_CHAR); } dam = (10 * level) + GET_AC(ch); break; case TRAP_DAM_SLASH: if ( !trap->whole_room ) { act("$n just got slashed by a trap on $p.", FALSE, ch, obj, 0, TO_ROOM); act("You just got slashed by a trap on $p!", FALSE, ch, obj, 0, TO_CHAR); } else { act("$n set off a trap releasing a blade that slashes you!", FALSE, ch, obj, 0, TO_ROOM); send_to_char("You set off a trap releasing blades around the room..\r\n", ch); send_to_char("One of the blades slashes you in the chest!\r\n", ch); } dam = (10 * level) + GET_AC(ch); break; default: return; } /* * Do the damage */ if ( !trap->whole_room ) { damage(ch, ch, dam, TYPE_UNDEFINED); } else { CHAR_DATA *wch_next = NULL; for (wch = ch->in_room->people; wch; wch = wch_next) { wch_next = wch->next_in_room; if (trap->dam_type == TRAP_DAM_BLUNT || trap->dam_type == TRAP_DAM_PIERCE || trap->dam_type == TRAP_DAM_SLASH) dam = (10 * level) + GET_AC(wch); damage(wch, wch, dam, TYPE_UNDEFINED); } } } bool check_trap(CHAR_DATA *ch, OBJ_DATA *obj, int action) { OBJ_TRAP_DATA *trap; bool trig = FALSE; if (!ch || !obj) return (FALSE); if (!obj->special || !OBJ_FLAGGED(obj, ITEM_HAS_TRAPS)) return (FALSE); for (trap = (OBJ_TRAP_DATA *) obj->special; trap; trap = trap->next) { if (IS_SET(trap->action, action)) break; } if (!trap) return (FALSE); if (trap->charges <= 0) return (FALSE); trap_damage(ch, obj, trap); return (TRUE); } /* ======================================================================= */ ACMD(do_trapremove) { OBJ_DATA *obj = NULL; OBJ_TRAP_DATA *trap_list, *trap, *next_trap = NULL, *temp; argument = one_argument(argument, arg); if (!GET_SKILL(ch, SKILL_DISARM_TRAPS)) { send_to_char("You don't know how to disarm traps.\r\n", ch); return; } if (!*arg) { send_to_char("From which object do you want to remove a trap?\r\n", ch); return; } if ( !( obj = get_obj_in_list_vis_rev(ch, arg, NULL, ch->in_room->last_content) ) ) { ch_printf(ch, "You don't see %s %s here.\r\n", AN(arg), arg); return; } if ( !obj->special || !OBJ_FLAGGED(obj, ITEM_HAS_TRAPS) ) { ch_printf(ch, "You don't find any traps on %s.\r\n", obj->short_description); return; } for ( trap = ( trap_list = (OBJ_TRAP_DATA *)obj->special ); trap; trap = next_trap ) { next_trap = trap->next; if (success(ch, NULL, SKILL_DISARM_TRAPS, 0)) { send_to_char("You successfully remove the trap.\r\n", ch); REMOVE_FROM_LIST(trap, trap_list, next); trap->next = NULL; DISPOSE(trap); } else { send_to_char("You set off the trap!\r\n", ch); if (trap->charges > 0) trap_damage(ch, obj, trap); else send_to_char("Luckily, it has no more charges.\r\n", ch); } } // if there is no traps left on the object, remove the trapped flag if (!(obj->special = trap_list)) REMOVE_BIT(GET_OBJ_EXTRA(obj), ITEM_HAS_TRAPS); } ACMD(do_trapstat) { OBJ_DATA *obj; OBJ_TRAP_DATA *trap; char tbuf[MAX_STRING_LENGTH], aflags[MAX_STRING_LENGTH]; if (!GET_SKILL(ch, SKILL_DISARM_TRAPS)) { send_to_char("You have no idea on how to handle traps.\r\n", ch); return; } argument = one_argument(argument, arg); if (!*arg) { send_to_char("Which object do you want to analyze?\r\n", ch); return; } // look first in room ... if (!(obj = get_obj_in_list_vis_rev(ch, str_dup(arg), NULL, ch->in_room->last_content))) { // ... and then in inventory if (!(obj = get_obj_in_list_vis_rev(ch, str_dup(arg), NULL, ch->last_carrying))) { sprintf(buf, "You don't see %s %s here.\r\n", AN(arg), arg); send_to_char(buf, ch); return; } } if ( !obj->special || !OBJ_FLAGGED(obj, ITEM_HAS_TRAPS) ) { send_to_char("That object has no trap.\r\n", ch); return; } send_to_char("&b&6Object is trapped:&0\r\n", ch); for ( trap = (OBJ_TRAP_DATA *)obj->special; trap; trap = trap->next ) { sprintbit( trap->action, trap_act_descr, aflags ); sprintf(tbuf, " Dam Type: %s, Charges: %d, Trigger: %s\r\n", trap_dam_descr[trap->dam_type], trap->charges, aflags); send_to_char(tbuf, ch); } } // Imm command ACMD(do_traplist) { OBJ_DATA *obj; bool found = FALSE; for (obj = first_object; obj; obj = obj->next) { if ( !obj->special || !OBJ_FLAGGED(obj, ITEM_HAS_TRAPS) || !CAN_SEE_OBJ(ch, obj)) continue; found = TRUE; if (obj->carried_by) sprintf(buf, "%s is being carried by %s.\r\n", obj->short_description, PERS(obj->carried_by, ch)); else if (obj->in_room != NULL) sprintf(buf, "%s is in %s.\r\n", obj->short_description, ROOM_NAME(obj)); else if (obj->in_obj) sprintf(buf, "%s is in %s.\r\n", obj->short_description, obj->in_obj->short_description); else if (obj->worn_by) sprintf(buf, "%s is being worn by %s.\r\n", obj->short_description, PERS(obj->worn_by, ch)); else sprintf(buf, "%s's location is uncertain.\r\n", obj->short_description); CAP(buf); send_to_char(buf, ch); } if (!found) send_to_char("No trapped items found.\r\n", ch); return; }