sts-term

Une version rudimentaire de Slay The Spire dans le terminal - retour accueil

git clone git://bebou.netlib.re/sts-term
Log | Files | Refs | README |

utils (15828B)


      1 #! /bin/sh
      2 
      3 grayed="\x1b[90m"
      4 norm="\x1b[0m"
      5 
      6 alias attack=":"
      7 alias skill=":"
      8 alias status=":"
      9 alias curse=":"
     10 alias ethereal=":"
     11 alias innate=":"
     12 
     13 _getstat() {
     14 	local target stat
     15 	target="$1";stat="$2"
     16 	grep -wF "$2" "$target" | cut -f2
     17 }
     18 
     19 power() {
     20 	local card
     21 	card="$1"
     22 	rm -rf $card
     23 }
     24 
     25 #####
     26 # UI
     27 #####
     28 
     29 _greyoutnonplayablecards() {
     30 	find fight/hand -type f |
     31 		grep -v -f $tmpdir/execcards |
     32 		xargs -r -n1 basename | sed -E 's/-[0-9]+$//' |
     33 		while read card;do
     34 			sed -i -E "/ $card$/ s/^/$grayed/;/$card/ s/$/$norm/" $tmpdir/hand
     35 		done
     36 }
     37 
     38 _createdisplaycard(){
     39 	local card name
     40 	card="$1";name="$(basename $card)"
     41 
     42 	<<-. cat > $tmpdir/disp-$name
     43 	$name
     44 	
     45 	$(cat $card |
     46 		grep -Ev "moves|bufs" |
     47 		sed -E 's/	/ : /')
     48 	
     49 	$(_dispbufsanddebufs $card)
     50 	
     51 	Next move :
     52 
     53 	$(cat $tmpdir/nextmove-$name | tr -d '_')
     54 	.
     55 }
     56 
     57 _dispbufsanddebufs() {
     58 	local target type
     59 	target="$1"
     60 
     61 	for type in bufs debufs;do
     62 		echo "$type"
     63 		grep -E "^$type" $target |
     64 			cut -sf2- |
     65 			tr '\t' '\n' |
     66 			sed 's/	/ : /' |
     67 			column -ts','
     68 	done
     69 }
     70 
     71 _showplayerstats() {
     72 	head player -n5 |
     73 		sed 's/	/ : /' |
     74 		awk '{printf $0"\t";getline;printf $0"\t";getline;printf $0"\t\n"}' |
     75 		sed -E 's/(gold : [0-9]+).*/\1/' |
     76 		column -ts'	'
     77 }
     78 
     79 _showpileofcards() {
     80 	local pile
     81 	pile="$1"
     82 	tree --noreport fight/$pile |
     83 		sed -E 's/-[0-9]+$//g;
     84 				s,fight/,,g'
     85 }
     86 
     87 _makeui() {
     88 	# Pour savoir combien de fois l'ui est rafraichie
     89 	# Clairement pas optimal mais drôle
     90 	# #ffplay -nodisp -autoexit -loglevel panic -f lavfi -i "sine=440:d=0.1"
     91 	[ ! -e "player" ] && printf "No current game\n"
     92 
     93 	currentenergy=$(_getstat player energy)
     94 	_updatecardexecutability
     95 
     96 	_showpileofcards stack > $tmpdir/stack
     97 	_showpileofcards hand > $tmpdir/hand
     98 	_showpileofcards discard > $tmpdir/discard
     99 	_showpileofcards exhaust > $tmpdir/exhaust
    100 
    101 	_greyoutnonplayablecards
    102 
    103 	for c in $(find fight/ennemies -type l) ;do
    104 		_createdisplaycard "$c"
    105 	done
    106 
    107 	<<-. cat
    108 	Floor : $(cat fight/floor)
    109 	Turn : $(cat fight/turn)
    110 
    111 	.
    112 
    113 	<<-. cat > $tmpdir/left-pane
    114 	$(_showplayerstats)
    115 
    116 	$(_dispbufsanddebufs player)
    117 
    118 	$(paste $tmpdir/disp-* | column -ts'	')
    119 
    120 	$(paste $tmpdir/stack $tmpdir/discard $tmpdir/exhaust | column -ts'	')
    121 	.
    122 
    123 	paste $tmpdir/left-pane $tmpdir/hand |
    124 		column -ts'	'
    125 }
    126 
    127 #####
    128 #
    129 ####
    130 
    131 _makefight() {
    132 	rm -rf fight
    133 
    134 	mkdir -p fight/ennemies
    135 	mkdir -p fight/stack
    136 	mkdir -p fight/hand
    137 	mkdir -p fight/discard
    138 	mkdir -p fight/exhaust
    139 
    140 	echo "1" > fight/turn
    141 	basename "$1" > fight/floor
    142 
    143 	cp deck/* fight/stack
    144 
    145 	for en in $(find "$1" -type f);do
    146 		ln -rs -f "$en" fight/ennemies/$(basename "$en")
    147 	done
    148 
    149 	ln -rs -f player fight/player
    150 	_setstat fight/player block 0
    151 	grep -EH "^innate" deck/* |
    152 		cut -d: -f1 |
    153 		while read card;do
    154 			echo "drawing innate $(basename $card)"
    155 			_draw 1 "$(basename $card)"
    156 		done
    157 	remcards="$(( 5 - $(find fight/hand -type f | wc -l) ))"
    158 	echo _draw "$remcards"
    159 	_draw "$remcards"
    160 	_setstat fight/player energy 3
    161 	_createnextmoves
    162 	_refreshUI
    163 }
    164 
    165 _exhaust() {
    166 	local card
    167 	card="$1"
    168 	echo "$card" | grep -q 'sentinel' &&
    169 		_changestat player energy +2
    170 	_hasstatus player dark-embrace && _draw 1
    171 	_hasstatus player feel-no-pain && { echo "gaining block from feel no pain"; _defend $(_getremainingstatusturns player feel-no-pain) player; }
    172 	echo mv "$card" fight/exhaust
    173 	mv "$card" fight/exhaust
    174 }
    175 
    176 _dupcard() {
    177 	local card dest howmuch
    178 	card="$2";dest="$3";howmuch="$1"
    179 	name="$(basename $card | sed -E 's/-[0-9]+$//')"
    180 	nbcard=$(find deck -name "$name-*" | wc -l)
    181 	echo "duplicating card $card instance of $name $howmuch times starting from id $(( $nbcard + 1 ))"
    182 	for i in $(seq $(( $nbcard + 1 )) $(( $nbcard + $howmuch )));do
    183 		cp $card $dest/$name-$i
    184 	done
    185 }
    186 
    187 _addcard() {
    188 	local howmuch name dest nbcard location
    189 	howmuch="$1";name="$2";dest="${3:-deck}"
    190 	nbcard=$(find deck -name "$2-*" | wc -l)
    191 	location=$(find bdd/cards -type f -name "$name")
    192 	for i in $(seq $(( $nbcard + 1 )) $(( $nbcard + $howmuch )));do
    193 		echo "adding card $name nb $i in $dest"
    194 		if [ "$name" = "wounds" ];then
    195 			cp bdd/cards/statuses/$name $dest/$name-$i
    196 		else
    197 			<<-. cat > $tmpdir/A
    198 			. ./utils
    199 			$(cat "$location" |
    200 				sed -E '/^[	 ]*_(cost|defend) /   s/$/ player/;
    201 						/^[	 ]*_(attack|status) / s/$/ "${1:?need a target}" fight\/player "$0"/;
    202 						/^[	 ]*_(heal) /          s/$/ "$0"/;
    203 						/^power/                  s/$/ "\$0"/
    204 						/^[	 ]*_exhaust$/         s/$/ "$0"/')
    205 			_discard "\$0"
    206 			_refreshUI
    207 			.
    208 			mv $tmpdir/A $dest/$name-$i
    209 		fi
    210 	done
    211 }
    212 
    213 _hasrelic() {
    214 	name="$1"
    215 	return $([ -e "relics/$1" ])
    216 }
    217 
    218 _wingold() {
    219 	currentgold=$(_getstat player gold)
    220 	_setstat player gold "$(( $currentgold + $(seq 10 20 | shuf | head -n1) ))"
    221 }
    222 
    223 _killennemie() {
    224 	local target card name
    225 	target="$1";card="${2:-something else}"
    226 	name="$(basename $target)"
    227 	echo "killed ennemie $target with card $card"
    228 	echo rm -rf "$(readlink -e $target)"
    229 	echo "$card" | grep -q "/feed-" && _changestat player maxhealth +3;
    230 	rm -rf "$(readlink -e $target)"
    231 	rm -rf "$target"
    232 	find $tmpdir -name "*$name*" |
    233 		xargs rm -rf
    234 	if [ $(find fight/ennemies -type l | wc -l) = '0' ];then
    235 		echo "end of combat"
    236 		_hasrelic burning-blood && _heal +6
    237 		_wingold
    238 		_refreshUI
    239 		_choosecard
    240 		_makefight map/$(( $(cat fight/floor) + 1 ))
    241 		exit 0
    242 	fi
    243 }
    244 
    245 # modifie d'une valeur relative
    246 # value doit avoir l'opérateur (+3, -3, *3)
    247 _changestat() {
    248 	local target stat value card
    249 	target="$1";stat="$2";value="$3";card="$4"
    250 	[ "$target" = "all" ] && {
    251 		target=$(find fight/ennemies -type l);}
    252 	echo "$target" | while read t;do
    253 		curvalue=$(_getstat "$t" "$stat")
    254 		_setstat "$t" "$stat" $(( $curvalue $value )) "$card"
    255 	done
    256 }
    257 
    258 # set la valeur absolue
    259 _setstat() {
    260 	local target stat value card
    261 	target="$1";stat="$2";value="$3";card="$4"
    262 	if [ "$stat" = "health" -a "$value" -le '0' ];then
    263 		case "$target" in
    264 			("*player*") _gameover;;
    265 			(*) _killennemie "$target" "$card";;
    266 		esac
    267 	fi
    268 	[ "$stat" = "block" ] && [ "$value" -gt "0" ] && _hasstatus player juggernaut &&
    269 		_dodamage $(_getremainingstatusturns player juggernaut) $(_randomennemy) player
    270 	echo sed -i --follow-symlinks -E "/^$stat	/ s/	.*/	$value/" "$target"
    271 	sed -i --follow-symlinks -E "/^$stat	/ s/	.*/	$value/" "$target"
    272 }
    273 
    274 _gameover() {
    275 	echo "game over" | toilet -f ansi > UI
    276 	sleep 2
    277 	./reset
    278 }
    279 
    280 _decrbfbcost() {
    281 	find fight -name '*blood-for-blood*' |
    282 		while read card;do
    283 			curcost=$(grep cost "$card" | cut -d' ' -f2)
    284 			sed -i -E "/_cost/ s/[0-9]/$(( $curcost - 1 ))/" "$card"
    285 		done
    286 }
    287 
    288 _dodamage() {
    289 	#ffplay -nodisp -autoexit -loglevel panic -i sounds/hit.ogg
    290 	local damage target hitter card targetblock targethealth newblock str;
    291 	damage="$1";target="$2";hitter="$3";card="$4"
    292 	echo "$target" | grep -q "player" && _decrbfbcost
    293 	$(echo "$target" | grep -q "player") && $(echo "$hitter" | grep -vq "player") && $(_hasstatus player flame-barrier) && {
    294 		echo returning damage : _dodamage $(_getremainingstatusturns player flame-barrier) "$hitter" player;
    295 		_dodamage $(_getremainingstatusturns player flame-barrier) "$hitter" player; }
    296 	echo "$target" | grep -q "player" && _decrbfbcost
    297 	targethealth=$(_getstat "$target" health);targetblock=$(_getstat "$target" block)
    298 	_hasstatus "$hitter" strength && str=$(_getremainingstatusturns "$hitter" strength) || str='0'
    299 	echo "using card $card"
    300 	echo "$card" | grep -q "heavy-blade" && str=$(( str*3 ))
    301 	_hasstatus "$hitter" weak && multiplier=0.75 || multiplier=1
    302 	_hasstatus "$target" vulnerable && multiplier=$(echo "$multiplier*1.5" | bc -l)
    303 	echo "($targetblock - ($damage+$str)*$multiplier)/1"
    304 	newblock=$(echo "($targetblock - ($damage+$str)*$multiplier)/1" | bc)
    305 	# Si la quantité de block qui reste est négative c'est qu'on prend cette
    306 	# quantité de dégât
    307 	# On remet le block à 0
    308 	[ "$newblock" -lt '0' ] && {
    309 		echo _changestat "$target" health "$newblock" "$card";
    310 		echo "$card" | grep -q "reaper-*" &&
    311 			_heal $(($newblock*-1)) "$card"
    312 		_changestat "$target" health "$newblock" "$card";
    313 		newblock=0 ;}
    314 	echo _setstat "$target" block "$newblock"
    315 	_setstat "$target" block "$newblock"
    316 }
    317 
    318 _attack() {
    319 	local damage times target hitter card
    320 	damage="$1";times="$2";target="$3";hitter="$4";card="$5"
    321 	_hasstatus player rage &&
    322 		_changestat player block "+$(_getremainingstatusturns player rage)"
    323 	[ "$target" = "all" ] && {
    324 		echo "attacking multiple ennemies";
    325 		target=$(find fight/ennemies -type l);
    326 		hitter="$5";card="$6";}
    327 	echo "$target" |
    328 	while read t;do
    329 		echo "damaging ennemie $t $times times with $damage damage"
    330 		for i in $(seq $times);do
    331 			echo _dodamage "$damage" "$t" "$hitter"
    332 			_dodamage "$damage" "$t" "$hitter" "$card"
    333 		done;
    334 	done
    335 }
    336 
    337 _defend() {
    338 	local block target
    339 	block="$1";target="$2"
    340 	echo _changestat "$target" block "+$block"
    341 	_changestat "$target" block "+$block"
    342 }
    343 
    344 _updatecardexecutability() {
    345 	currentenergy=$(_getstat player energy)
    346 	grep -EH "^_cost" fight/hand/* |
    347 		awk "\$2<=$currentenergy{print}" |
    348 		cut -d':' -f1 |
    349 		xargs -r chmod +x
    350 
    351 	grep -EH "^_cost" fight/hand/* |
    352 		awk "\$2>$currentenergy{print}" |
    353 		cut -d':' -f1 |
    354 		xargs -r chmod -x
    355 
    356 	nbcard=$(find fight/hand -type f | wc -l)
    357 	nbattacks=$(grep "^attack" fight/hand/* | wc -l)
    358 	[ ! "$nbcard" = "$nbattack" ] && [ -e "fight/hand/clash-1" ] &&
    359 		chmod -x fight/hand/clash-*
    360 
    361 	find fight/hand -type f -executable | xargs -r -n1 basename > $tmpdir/execcards
    362 
    363 }
    364 
    365 _cost() {
    366 	local cost
    367 	cost="$1"
    368 	currentenergy=$(_getstat player energy)
    369 	newenergy=$(( $currentenergy - $cost ))
    370 	_setstat fight/player energy "$newenergy"
    371 }
    372 
    373 _shufflediscard() {
    374 	mv fight/discard/* fight/stack
    375 }
    376 
    377 _choosecard() {
    378 	find bdd/cards/red -type f |
    379 		grep -Ev '(strike|defend|bash)$' |
    380 		shuf |
    381 		head -n3 |
    382 		xargs -n1 basename |
    383 		sed '$ a\skip' |
    384 		fzy |
    385 		while read card;do
    386 			[ "$card" = "skip" ] && break
    387 			_addcard 1 "$card"
    388 		done
    389 }
    390 
    391 _nodraw () {
    392 	echo
    393 }
    394 
    395 _heal() {
    396 	local amount src
    397 	amount="$1";src="$2"
    398  	maxhealth=$(_getstat player maxhealth)
    399 	[ "$amount" -lt "0" ] \
    400 	&& echo "$src" | grep -q "fight/hand" \
    401 	&& _hasstatus player rupture &&
    402 		_strength "1" player
    403 	newhealth=$(( $(_getstat player health | cut -f2) + $amount ))
    404 	echo _setstat fight/player health $(( $newhealth > $maxhealth ? $maxhealth : $newhealth ))
    405 	_setstat fight/player health $(( $newhealth > $maxhealth ? $maxhealth : $newhealth ))
    406 }
    407 
    408 _exetherealcard() {
    409 	grep -HE '^ethereal' fight/hand/* |
    410 		cut -d: -f1 |
    411 		while read card;do _exhaust "$card"; done
    412 }
    413 
    414 endturn() {
    415 	_exetherealcard
    416 	for e in $(find fight/ennemies -type l);do
    417 		_setstat $e block 0
    418 	done
    419 	_hasstatus player metallicize &&
    420 		_defend $(_getremainingstatusturns player metallicize) player
    421 	_hasstatus player combust && {
    422 		v="$(_getremainingstatusturns player combust)"
    423 		_heal "-$v" fight/hand
    424 		for i in $(find fight/ennemies -type l);do _dodamage $((5*$v)) $i player;done ;}
    425 	_execnextmove
    426 	_hasstatus player demon-form &&
    427 		_status strength $(_getremainingstatusturns player demon-form) player
    428 	[ $(find fight/hand -name 'burn-*' | wc -l) -gt '0' ] &&
    429 		chmod +x fight/hand/burn-*;find fight/hand -name 'burn-*' | sh
    430 	_hasstatus player barricade ||
    431 		_setstat fight/player block 0
    432 	_setstat fight/player energy 3
    433 	_hasstatus player berserk &&
    434 		_changestat player energy "+$(_getremainingstatusturns player berserk)"
    435 	_hasstatus player strength-down && {
    436 		_status strength "-$(_getremainingstatusturns player strength-down)" player;
    437 		_removestatus player strength-down; }
    438 	_decreasestatuses
    439 	_removestatus player flame-barrier
    440 	_removestatus player rage
    441 	_createnextmoves
    442 	_newhand
    443 	_hasstatus player brutality && {
    444 		_heal -3 fight/hand;
    445 		_draw 1; }
    446 	echo "$(( $(cat fight/turn) + 1 ))" > fight/turn
    447 	_refreshUI
    448 }
    449 
    450 _draw() {
    451 	local nbtodraw card
    452 	_hasstatus player no-draw && return 0
    453 	nbtodraw="$1";innatecard="$2"
    454 	for nb in $(seq "$nbtodraw");do
    455 		[ "$(find fight/stack -type f | wc -l)" = "0" ] && _shufflediscard
    456 		[ -z "$innatecard" ] \
    457 		&& card=$(find fight/stack -type f | shuf | head -n 1) \
    458 		|| card="fight/stack/$innatecard"
    459 		chmod +x "$card"
    460 		cardtype=$(sed -n '2 p' "$card")
    461 		echo mv "$card" fight/hand of type $cardtype
    462 		mv "$card" fight/hand
    463 		_hasstatus player fire-breathing && [ "$cardtype" = "status" -o "$cardtype" = "curse" ] && {
    464 			v=$(_getremainingstatusturns player fire-breathing);
    465 			for i in $(find fight/ennemies -type l);do _dodamage $v $i player;done ;}
    466 		_hasstatus player evolve && [ "$cardtype" = "$status" ] &&
    467 			_draw 1
    468 	done
    469 }
    470 
    471 _newhand() {
    472 	local nb
    473 	nb="${1:-5}"
    474 	find fight/hand -type f |
    475 		while read card;do
    476 			_discard "$card"
    477 		done
    478 	_draw $nb
    479 }
    480 
    481 _discard() {
    482 	card="$1"
    483 	[ -e "$card" ] && {
    484 		chmod -x "$card";
    485 		mv "$card" fight/discard;}
    486 }
    487 
    488 _refreshUI() {
    489 	_makeui > UI
    490 }
    491 
    492 #####
    493 # Statuses
    494 #####
    495 
    496 _status() {
    497 	local stat nbturns target
    498 	stat="$1";nbturns="$2";target="$3"
    499 	case "$stat" in
    500 		(vulnerable|weak|strength-down) type="debufs";;
    501 		(*)               type="bufs";;
    502 	esac
    503 	[ "$target" = "all" ] &&
    504 		target=$(find fight/ennemies -type l)
    505 	echo "$target" | while read t;do
    506 		if $(_hasstatus "$t" "$stat");then
    507 			remturn=$(_getremainingstatusturns "$t" "$stat")
    508 			totturns=$(( $nbturns + ${remturn:-0} ))
    509 			if [ "$totturns" = "0" ];then
    510 				_removestatus "$t" "$stat"
    511 			else
    512 				echo sed --follow-symlinks -i -E "/^$type/ s/$stat,-?[0-9]+/$stat,$totturns/" "$t"
    513 				sed --follow-symlinks -i -E "/^$type/ s/$stat,-?[0-9]+/$stat,$totturns/" "$t"
    514 			fi
    515 		else
    516 			echo sed --follow-symlinks -i -E "/^$type/ s/$/	$stat,$nbturns/" "$t"
    517 			[ "$stat" = "corruption" ] && {
    518 				grep -rH "^skill" fight | cut -d':' -f1 |
    519 				xargs -r sed -i -E '/^_cost/ s/[0-9]/0/;
    520 				                    /^_discard/ i\_exhaust "$0"';
    521 				_updatecardexecutability;}
    522 			sed --follow-symlinks -i -E "/^$type/ s/$/	$stat,$nbturns/" "$t"
    523 		fi
    524 	done
    525 }
    526 
    527 _getstatuses() {
    528 	local target
    529 	target="$1"
    530 	grep -E '^(de)?bufs	' "$target" |
    531 		cut -f2- |
    532 		tr '	' '\n' |
    533 		grep -Ev '(strength|dark-embrace|feel-no-pain|metallicize|rupture|barricade|berserk|brutality|demon-form|juggernaut|combust|corruption|evolve|fire-breathing)' |
    534 		cut -d',' -f1
    535 }
    536 
    537 _decreasestatuses() {
    538 	statuses=$(_getstatuses player)
    539 	if [ ! -z "$statuses" ];then
    540 		echo "$statuses" |
    541 		while read stat;do
    542 			_status "$stat" -1 player
    543 		done
    544 	fi
    545 	find fight/ennemies/* -type l |
    546 		while read ennemy;do
    547 			statuses=$(_getstatuses "$ennemy")
    548 			[ -z "$statuses" ] && continue
    549 			echo "$statuses" |
    550 			while read stat;do
    551 				_status "$stat" -1 "$ennemy"
    552 			done
    553 		done
    554 }
    555 
    556 _hasstatus() {
    557 	local target stat
    558 	target="${1:?need target}";stat="$2"
    559 	grep -Eq "^(de)?bufs.*$stat,-?[0-9]+" "$target"
    560 }
    561 
    562 _getremainingstatusturns() {
    563 	local target stat
    564 	target="$1";stat="$2"
    565 	grep -Eo "	$stat,-?[0-9]+" "$target" | cut -d',' -f2
    566 }
    567 
    568 _removestatus() {
    569 	local target stat
    570 	target="$1"
    571 	stat="$2"
    572 	sed -i -E --follow-symlinks "/^(de)?bufs/ s/	$stat,[0-9]+//" "$target"
    573 }
    574 
    575 #####
    576 # Ennemies
    577 #####
    578 
    579 _createnextmoves() {
    580 
    581 	find fight/ennemies/ -type l |
    582 	while read en;do
    583 		id=$(basename $en)
    584 		grep moves "$en" |
    585 		cut -f2- |
    586 		tr '	' '\n' |
    587 		shuf | head -n1 |
    588 		tr ',' ' ' | tr ';' '\n' > $tmpdir/nextmove-$id
    589 	<<-. cat > $tmpdir/executablenextmove-$id
    590 	. ./utils
    591 	$(< $tmpdir/nextmove-$id sed -E "/attack/ s,$, fight/player $en,;/defend/ s,$, $en,")
    592 	.
    593 	done
    594 
    595 	chmod +x $tmpdir/executablenextmove-*
    596 }
    597 
    598 _execnextmove() {
    599 	echo $tmpdir/executablenextmove-* |
    600 		tr ' ' ';' |
    601 		sh
    602 }
    603 
    604 ####
    605 # Cards
    606 ####
    607 # Les fonctions appelées pas les cartes
    608 
    609 _strength() {
    610 	local value target
    611 	value="$1";target="$2"
    612 	_status strength "$value" "$target"
    613 }
    614 
    615 #####
    616 # Interaction
    617 #####
    618 
    619 choice() {
    620 	c=$(find fight/hand -type f | fzy)
    621 	$(echo "$c" | grep -Eq "(defend|shrug-it-off)") && { eval $c; return 0; }
    622 	t=$(find fight/ennemies -type l | fzy)
    623 	_hasstatus player double-tap \
    624 	&& cat "$c" | grep -q '^_attack' && {
    625 		< $c sed -E '/^_cost/ s/[0-9]/0/
    626 		             /^_discard/ s/.*/rm -rf "$0"/' > $tmpdir/doubled;
    627 		chmod +x $tmpdir/doubled;
    628 		eval $tmpdir/doubled $t;
    629 		_status double-tap -1 player; }
    630 	eval $c $t
    631 }