====== Bash functions to handle Traps ====== This function library contains bash shell functions related to the [[:skills:Find Traps]] and [[:skills:Disarm Traps]] skills. \\ Though it had been tested with the busybox ash shell, some functions might only work correctly in bash ( or the other way around ). The functions use code from - [[cf_funcs_common_sh]] These [[:client side scripting]] files are suggested to be installed inside the user's "HOME/.crossfire/s/" folder, \\ with a shortcut link cf -> to the **.**[[:client:crossfire]] directory, \\ to do have not much typing to do in the [[:client]]'s commandline. Functions are usually named **_**function(){ ;} , functions named **_ _**function and **_ _ _**function are alternatives to the _function. The main functions are **_search_traps** and **_disarm_traps** . \\ _disarm_traps forks to call the desired function according to the DISARM variable. \\ The DISARM variable can be set to "skill", "invocation", "cast"; to enable a switch to either use the skill of disarm traps \\ or to cast or to invoke the sorcery spell disarm. When severe Runes are detected, then the script exits : Ball Lightning, Bomb, Summoning . \\ Other trap effects are ignored; so make sure, the character has enough hit points \\ to receive punishment without dying, and or is able to heal diseases and poisons inflicted by needles. ===== The Code == 330 lines of code without much explanations... #!/bin/ash [ "$HAVE_FUNCS_TRAPS" ] && return 0 # depends : [ "$HAVE_FUNCS_COMMON" ] || . cf_funcs_common.sh _disarm_traps(){ _draw 5 "Disarming ${TRAPS_ALL:-0} traps ..." case "$DISARM" in invokation|invocation) _invoke_disarm;; cast|spell) #case "$DIRECTION" in '') _invoke_disarm;; *) _cast_disarm;; esac;; _cast_disarm;; skill|'') _use_skill_disarm;; *) _error "DISARM variable set not to skill, invokation OR cast'";; esac } _use_skill_skill(){ _debug "_use_skill_skill:$*" local lSKILL=${*:-$SKILL} test "$lSKILL" || return 254 local cnt0 while : do _draw 5 "Using skill $lSKILL ..." #echo watch $DRAWINFO _watch $DRAWINFO _is 0 0 use_skill $lSKILL _sleep unset REPLY OLD_REPLY cnt0 while : do cnt0=$((cnt0+1)) read -t $TMOUT _log "_use_skill_skill:$cnt0:$REPLY" _msg 7 "$cnt0:$REPLY" #You fail to disarm the Rune of Burning Hands. #In fact, you set it off! #You detonate a Rune of Burning Hands! #You successfully disarm the spikes! #You fail to disarm the Rune of Icestorm. case $REPLY in *'You successfully disarm'*) TRAPS=$((TRAPS-1));; *'You fail to disarm'*) :;; *'In fact, you set it off!'*) TRAPS=$((TRAPS-1));; *'You detonate'*) _just_exit 1;; *'A portal opens up, and screaming hordes pour'*) _just_exit 1;; *'through!'*) _just_exit 1;; *"RUN! The timer's ticking!"*) _just_exit 1;; *'You are pricked'*) :;; *'You are stabbed'*) :;; *scripttell*break*) break ${REPLY##*?break};; *scripttell*exit*) _exit 1 $REPLY;; *'YOU HAVE DIED.'*) _just_exit;; '') break 1;; *) :;; esac _sleep test "$OLD_REPLY" = "$REPLY" && break 1 OLD_REPLY=$REPLY done _unwatch $DRAWINFO _move_back_and_forth 2 _sleep done unset OLD_REPLY } _use_skill_disarm(){ _debug "_use_skill_disarm:$*" test "$TRAPS_ALL" || return 0 test "${TRAPS_ALL//[0-9]/}" && return 2 test "$TRAPS_ALL" -gt 0 || return 0 TRAPS=$TRAPS_ALL while : do _draw 5 "${TRAPS:-0} trap(s) to disarm ..." #echo watch $DRAWINFO _watch $DRAWINFO _is 0 0 use_skill disarm _sleep local cnt0 unset REPLY OLD_REPLY cnt0 while : do cnt0=$((cnt0+1)) read -t $TMOUT _log "_use_skill_disarm:$cnt0:$REPLY" _msg 7 "$cnt0:$REPLY" #You fail to disarm the Rune of Burning Hands. #In fact, you set it off! #You detonate a Rune of Burning Hands! #You successfully disarm the spikes! #You fail to disarm the Rune of Icestorm. case $REPLY in *'You successfully disarm'*) TRAPS=$((TRAPS-1));; *'You fail to disarm'*) :;; *'In fact, you set it off!'*) TRAPS=$((TRAPS-1));; *'You detonate'*) _just_exit 1;; *'A portal opens up, and screaming hordes pour'*) _just_exit 1;; *'through!'*) _just_exit 1;; *'You are pricked'*) :;; *scripttell*break*) break ${REPLY##*?break};; *scripttell*exit*) _exit 1 $REPLY;; *'YOU HAVE DIED.'*) _just_exit;; '') break 1;; *) :;; esac _sleep test "$OLD_REPLY" = "$REPLY" && break 1 OLD_REPLY=$REPLY done _unwatch $DRAWINFO _move_back_and_forth 2 _sleep test "$TRAPS" -gt 0 || break 1 done unset OLD_REPLY } _invoke_disarm(){ ## invoking does to a direction _debug "_invoke_disarm:$*" test "$TRAPS_ALL" || return 0 test "${TRAPS_ALL//[0-9]/}" && return 2 test "$TRAPS_ALL" -gt 0 || return 0 TRAPS=$TRAPS_ALL _move_back 2 _move_forth 1 _sleep while : do _draw 5 "${TRAPS:-0} trap(s) to disarm ..." #echo watch $DRAWINFO _watch $DRAWINFO _is 0 0 invoke disarm _sleep #There's nothing there! #You fail to disarm the diseased needle. #You successfully disarm the diseased needle! unset REPLY OLD_REPLY cnt0 while : do cnt0=$((cnt0+1)) read -t $TMOUT _log "_invoke_disarm:$cnt0:$REPLY" _msg 7 "$cnt0:$REPLY" case $REPLY in *'You successfully disarm'*) TRAPS=$((TRAPS-1)); break 1;; *'You fail to disarm'*) break 1;; # Here there could be a trap next to the stack of chests ... # so invoking disarm towards the stack of chests would not # work to disarm the traps elsewhere on tiles around *"There's nothing there!"*) break 2;; *'A portal opens up, and screaming hordes pour'*) _just_exit 1;; *'through!'*) _just_exit 1;; *scripttell*break*) break ${REPLY##*?break};; *scripttell*exit*) _exit 1 $REPLY;; *'YOU HAVE DIED.'*) _just_exit;; *) :;; esac done _unwatch $DRAWINFO _sleep test "$TRAPS" -gt 0 || break 1 done _unwatch $DRAWINFO _move_forth 1 } _cast_disarm(){ _debug "_cast_disarm:$*" test "$TRAPS_ALL" || return 0 test "${TRAPS_ALL//[0-9]/}" && return 2 test "$TRAPS_ALL" -gt 0 || return 0 TRAPS=$TRAPS_ALL while : do _draw 5 "${TRAPS:-0} trap(s) to disarm ..." # TODO: checks for enough mana #echo watch $DRAWINFO _watch $DRAWINFO _is 0 0 cast disarm _sleep _is 0 0 fire 0 _is 0 0 fire_stop _sleep unset REPLY OLD_REPLY cnt0 while : do cnt0=$((cnt0+1)) read -t $TMOUT _log "_cast_disarm:$cnt0:$REPLY" _msg 7 "$cnt0:$REPLY" case $REPLY in *'You successfully disarm'*) TRAPS=$((TRAPS-1)); break 1;; *'You fail to disarm'*) break 1;; *"There's nothing there!"*) break 2;; *'A portal opens up, and screaming hordes pour'*) _just_exit 1;; *'through!'*) _just_exit 1;; *scripttell*break*) break ${REPLY##*?break};; *scripttell*exit*) _exit 1 $REPLY;; *'YOU HAVE DIED.'*) _just_exit;; *) :;; esac sleep 0.1 done _unwatch $DRAWINFO _sleep test "$TRAPS" -gt 0 || break 1 done _unwatch $DRAWINFO } _search_traps(){ _debug "_search_traps:$*" cnt=${SEARCH_ATTEMPTS:-$SEARCH_ATTEMPTS_DEFAULT} #_draw 5 "Searching traps ..." test "$cnt" -gt 0 || return 0 TRAPS_ALL_OLD=0 TRAPS_ALL=$TRAPS_ALL_OLD while : do _draw 5 "Searching traps $cnt time(s) ..." #echo watch ${DRAWINFO} _watch ${DRAWINFO} _sleep _is 0 0 search #_sleep unset cnt0 FOUND_TRAP while : do cnt0=$((cnt0+1)) unset REPLY read -t $TMOUT _log "_search_traps:$cnt0:$REPLY" _msg 7 "$cnt0:$REPLY" #You spot a Rune of Burning Hands! #You spot a poison needle! #You spot a spikes! #You spot a Rune of Shocking! #You spot a Rune of Icestorm! #You search the area. #You spot a Rune of Ball Lightning! case $REPLY in *'You spot a Rune of Ball Lightning!'*) _just_exit 0;; *'You spot a Rune of Create Bomb!'*) _just_exit 0;; *' spot '*) FOUND_TRAP=$((FOUND_TRAP+1));; *'You search the area.'*) SEARCH_MSG=$((SEARCH_MSG+1));; # break 1;; *scripttell*break*) break ${REPLY##*?break};; *scripttell*exit*) _exit 1 $REPLY;; *'YOU HAVE DIED.'*) _just_exit;; '') break 1;; *) :;; esac sleep 0.1 done test "$FOUND_TRAP" && _draw 2 "Found $FOUND_TRAP trap(s)." TRAPS_ALL=${FOUND_TRAP:-$TRAPS_ALL} _debug "TRAPS_ALL=$TRAPS_ALL" test "$TRAPS_ALL_OLD" -gt $TRAPS_ALL && TRAPS_ALL=$TRAPS_ALL_OLD _debug "TRAPS_ALL=$TRAPS_ALL" TRAPS_ALL_OLD=${TRAPS_ALL:-0} _debug "FOUND_TRAP=$FOUND_TRAP TRAPS_ALL_OLD=$TRAPS_ALL_OLD" _unwatch $DRAWINFO _sleep test "$MULTIPLE_TRAPS" || { test "$TRAPS_ALL" -ge 1 && break 1; } cnt=$((cnt-1)) test "$cnt" -gt 0 || break 1 done unset cnt } ###END### HAVE_FUNCS_TRAPS=1