==== Melting masses of ice cubes ====
What for a nasty situation : You used some icestorm spell to eliminate some monsters,
but now almost all items on the ground are boxed inside an one-time ice cube container.
Collecting all these ice-cubes and manually typing :
mark icecube; apply flint and steel
inside the command line of the client several dozen times is exhausting;
so better make a script that does all that typing for you.
This script uses functions from a source-able library file
* [[client_side_scripting:scripts:bash:cf_funcs_common]]
and would likely not work without these functions.
Functions() completely written in this script are
* _mark_item() that tests if the input pipe streams `Could not find an object that matches' to stop the loop.
* _apply_item() that tests the many responses from applying the flint and steel on the icecube and breaks the loop if these are used up, not available, or nothing was marked.
* _say_count() to finally say how many failures and successes were made.
==== Code ==
#!/bin/bash
VERSION=0.0
VERSION=1.0 # posted on forum.metalforge.net
VERSION=2.0 # 2018-01-10 code overhaul now using functions, posted on wiki.cross-fire.org
VERSION=2.1 # 2018-02-17 more code overhauling
Version=2.2 # 2018-04-16 code overhaul
MARK_ITEM='icecube' # item to mark in function _mark_item()
ITEM='flint and steel' # item to apply in function _apply_item()
DEBUG='' #1 # empty string or anything
MSGLEVEL=6 #7 # 0 - 7
LOGGING='' #1 # empty string or anything
MY_SELF=`realpath "$0"`
MY_BASE=${MY_SELF##*/}
MY_DIR=${MY_SELF%/*}
test -f "$MY_DIR"/cf_funcs_common.sh && . "$MY_DIR"/cf_funcs_common.sh
_set_global_variables "$@"
cd "$MY_DIR"
# *** Override any VARIABLES in cf_functions.sh *** #
test -f "$MY_DIR"/"${MY_BASE}".conf && . "$MY_DIR"/"${MY_BASE}".conf
unset DIRB DIRF # for _exit()
# functions:
_say_help(){
_draw 2 "$MY_BASE"
_draw 2 "Script to melt icecubes in inventory."
_draw 4 "To be used in the crossfire roleplaying game client."
_draw 2 "Syntax:"
_draw 2 "script $MY_SELF <>"
_draw 2 "For example: 'script $MY_SELF 5'"
_draw 2 "will issue mark icecube and apply flint and steel"
_draw 2 " until 5 icecubes have been melt."
exit 0
}
_mark_item(){
# returns not 0, if message says
# no match
_debug "_mark_item:$*"
_log "_mark_item:$*"
local lITEM=${*:-"$MARK_ITEM"}
lITEM=${lITEM:-"$ITEM"}
lITEM=${lITEM:-icecube}
test "$lITEM" || return 254
local lRV=0
_is 1 1 mark "$lITEM"
while :; do
unset REPLY
read -t $TMOUT
_log "_mark_item:$REPLY"
_debug "$REPLY"
case $REPLY in
*Could*not*find*an*object*that*matches*) lRV=1;break 1;;
*scripttell*break*) break ${REPLY##*?break};;
*scripttell*exit*) _exit 1 $REPLY;;
*'YOU HAVE DIED.'*) _just_exit;;
'') break;;
esac
sleep 0.1
done
return ${lRV:-0}
}
_apply_item(){
# returns 0 on success,
# -gt 0 otherwise
_debug "_apply_item:$*"
_log "_apply_item:$*"
local lITEM=${*:-"$ITEM"}
lITEM=${lITEM:-"flint and steel"}
test "$lITEM" || return 254
local lRV=0
_is 1 1 apply "$lITEM"
while :; do
unset REPLY
read -t $TMOUT
_log "_apply_item:$REPLY"
_debug "$REPLY"
case $REPLY in
*You*light*the*icecube*with*the*flint*and*steel.*) lRV=0; SUCC=$((SUCC+1)); break 1;;
*fail*used*up*flint*and*steel*) lRV=5; break 1;;
*fail*) lRV=1; FAIL=$((FAIL+1)); break 1;;
*Could*not*find*any*match*to*the*flint*and*steel*) lRV=6; break 1;;
*You*need*to*mark*a*lightable*object.*) lRV=7; break 1;;
*scripttell*break*) break ${REPLY##*?break};;
*scripttell*exit*) _exit 1 $REPLY;;
*'YOU HAVE DIED.'*) _just_exit;;
'') lRV=1; break 1;;
*) :;;
esac
sleep 0.1
done
return ${lRV:-0}
}
_say_count(){
case $SUCC in [0-9]*) _draw 7 "You had melt $SUCC icecube(s).";; esac
case $FAIL in [0-9]*) _draw 4 "You tried $FAIL time(s) with failure.";; esac
}
# *** Here begins program *** #
# *** Check for parameters *** #
while [ "$1" ]
do
PARAM_1="$1"
# *** implementing 'help' option *** #
case "$PARAM_1" in
-h|*"help"*) _say_help;;
-d) DEBUG=$((DEBUG+1));;
-L) LOGGING=$((LOGGING+1));;
-V) _say_version;;
*) # *** testing parameters for validity *** #
PARAM_1test="${PARAM_1//[[:digit:]]/}"
test "$PARAM_1test" && _exit 1 "Only :digit: numbers as first option allowed."
#exit if other input than letters
NUMBER=$PARAM_1
;;
esac
shift
sleep 0.1
done
# Prerequsites: DRAWINFO variable,
# prevent multiple scripts running,
# set sleep values according to player speed
_say_start_msg "$@"
# *** Getting Player's Speed *** #
_get_player_speed
#_set_sync_sleep ${PL_SPEED1:-$PL_SPEED}
test "$PL_SPEED1" && __set_sync_sleep ${PL_SPEED1} || _set_sync_sleep "$PL_SPEED"
test "$NUMBER" && { test $NUMBER -ge 1 || NUMBER=1; } #paranoid precaution
_debug "NUMBER='$NUMBER'"
SUCC=0 # count the successful attempts
FAIL=0 # count the failure attempts
# *** Actual script to pray multiple times *** #
# MAIN
_watch $DRAWINFO
unset one
while :
do
one=$((one+1))
_mark_item icecube || break 2
_sleep
while :;
do
_apply_item "flint and steel"
case $? in
0) break 1;; #success
1) :;; #try again
2) :;; #unused
3) :;; #unused
4) :;; #unused
5) #used up
_warn "Your flint and steel is used up.";
break 2;;
6) break 2;; #no item
7) break 1;; #not marked
8) :;; #unused
9) :;; #unused
esac
#_say_count
_sleep
done
case $NUMBER in $one) break 1;; esac
_say_count
done #main while loop
# *** Here ends program *** #
_say_count
_say_end_msg
###END###
The usual disclaimer :
If [parts of] the script do[es] not work for you, you are welcome to post a bug report on
the metalforge forum in [[http://forum.metalforge.net/viewtopic.php?p=12220|my thread `bash']]