#!/bin/bash # # journeymap_join [options] [--] [output_map] # # Join the given maps. So as to display or save. # # Note that 'mask' images (of the form "*_mask.png") will be overlayed on # the tile image before merging. # # If one argument join all maps in directory to that map # If more than one display those maps # If no arguments, update the obsidian cental day maps # # COMMON RUNS: # journeymap_join # overworld daytime map # journeymap_join -ms n # overworld nighttime map (find torches, lava) # journeymap_join -md e # what have you explored in the end # # OPTIONS: # -mw set The map world (def: CubeKrowd) # -md set The dimention of the map world: one of o,e,n # -ms set Set of maps to use (day,night,topo,1,2,3,...) # -mp path Just use this path to the map numbers (overrides -s set) # # -ls List the map directory and exit # # -l # limit area looked at (remove outliners -1=unlimited) # -q [-+][-+] Limit map to just one quarter. # -c #,# Center map of area limited (floor of coords/512) # -C include middle of map coordinate in image (use -c if set) # # -- end of options (leaving just the output filename) # ### # # # Anthony Thyssen 22 Feburary 2016 # # Discover where the shell script resides PROGNAME=`type "$0" | awk '{print $3}'` # search for executable on path PROGDIR="${PROGNAME%/*}" # extract directory of program PROGNAME="${PROGNAME##*/}" # base name of program ORIGDIR=`pwd -P` # original directory # normal /tmp overflows export MAGICK_TMPDIR="$PROGDIR" Usage() { # Report error and Synopsis line only echo >&2 "$PROGNAME:" "$@" sed >&2 -n '1,2d; /^###/q; /^#/!q; /^#$/q; s/^# */Usage: /p;' \ "$PROGDIR/$PROGNAME" exit 10; } Help() { # Output Full header comments as documentation sed >&2 -n '1d; /^###/q; /^#/!q; s/^#//; s/^ //; p' \ "$PROGDIR/$PROGNAME" exit 10; } Error() { # Just output an error condition and exit (no usage) echo >&2 "$PROGNAME:" "$@" exit 2 } # Defaults (typically based on current directory) JOURNEY_MAPS="$HOME/apps/journeymap/data/mp" JOURNEY_MAPS_SP="$HOME/apps/journeymap/data/sp" MAP_DIM="0" MAP_SET="day" case $(pwd) in */servers) MAP_WORLD="Flatland" JOURNEY_MAPS=$JOURNEY_MAPS_SP ;; */CoreJourney) MAP_WORLD="Core~Journey" ;; */Element*) MAP_WORLD="Element~Animation~Server" ;; */CubeKrowd/su*) MAP_WORLD="CubeKrowd" ;; # server in maps area */CubeKrowd/Creative) MAP_WORLD="CubeKrowd_cr" ;; # server in maps area esac LIMIT=-1 # no limits just montage all the maps CENTER_X=0 # Center of the limit CENTER_Y=0 # Center of the limit # Location for convert cache export MAGICK_TMPDIR=/extra # option handling while [ $# -gt 0 ]; do case "$1" in # Standard help option. -\?|-help|--help|--doc*) Help ;; -mw) shift; MAP_WORLD="$1" ;; # The map world to look at -md) shift; MAP_DIM="$1" ;; # The dimension of that world (o,e,n) -ms) shift; MAP_SET="$1" ;; # Map sub-set of the world (d,n,t) -mp) shift; MAP_PATH="$1" ;; # directory use this path to map files -ls) LIST_MAPS="true" ;; # just list the map directory and exit -l) shift; LIMIT=$1 ;; # limit area to remove outliners -q) shift; QUARTER=$1 ;; # limit to just one quarter of map EG -q +- -C) ADD_COORD=true ;; # add middle coord to output image name -c) if [[ "$2" =~ ([-+]?[0-9]+),([-+]?[0-9]+) ]]; then CENTER_X="${BASH_REMATCH[1]}" # note center is in map tile coords CENTER_Y="${BASH_REMATCH[2]}" COORD_SET=true else Usage "Bad Geometry" fi ; shift ;; --) shift; break ;; # forced end of user options -*) Usage "Unknown option \"$1\"" ;; *) break ;; # unforced end of user options esac shift # next option done # Only thng left is a optional destination filename (with suffix) [ $# -gt 2 ] && Usage "Too Many Arguments" if [[ ! -v MAP_PATH ]]; then if [[ -z "$MAP_WORLD" || ! -d $JOURNEY_MAPS/$MAP_WORLD ]]; then echo >&2 "$PROGNAME: World (Server) not set -mw $MAP_WORLD" echo >&2 "Select from..." ls >&2 $JOURNEY_MAPS exit 2 fi # Set default output filename case "$MAP_DIM" in o|0|overworld) MAP_DIM=overworld ;; e|1|end) MAP_DIM=the_end; OUTPUT=end ;; n|-1|nether) MAP_DIM=the_nether; OUTPUT=nether ;; *) echo >&2 "PROGNAME: Unknown dimension -md \"$MAP_DIM\"" echo >&2 "Select from..." ls >&2 $JOURNEY_MAPS/$MAP_WORLD exit 2 ;; esac if [ "X$MAP_DIM" == 'Xoverworld' ]; then case "$MAP_SET" in d|day) MAP_SET=day ;; n|night) MAP_SET=night ;; t|topo) MAP_SET=topo ;; [0-7]|-[1-4]) ;; *) echo >&2 "PROGNAME: Unknown map set -ms \"$MAP_SET\")" echo >&2 "Select from..." ls >&2 $JOURNEY_MAPS/$MAP_WORLD/$MAP_DIM exit 2 ;; esac case "$MAP_SET" in [0-7]) OUTPUT=ugnd_${MAP_SET} ;; *) OUTPUT=${MAP_SET} ;; esac fi # the directory of maps to join together MAP_PATH="$JOURNEY_MAPS/$MAP_WORLD/$MAP_DIM/$MAP_SET" fi echo "Map Path: $MAP_PATH" # switch to the directory with the maps cd "$MAP_PATH" [[ $? -ne 0 ]] && Error "Map Path Change Directory Failure" # just list the map directory if [ "$LIST_MAPS" ]; then ls "$MAP_PATH" exit 0 fi if [ ${#maps[@]} -eq 0 ]; then maps=( *,*.png ) fi #echo "${#maps[@]} maps =>" ${maps[@]} if [ "X$maps" = "X*,*.png" ]; then Error "No Maps Found in \"$MAP_PATH\"" fi OUTPUT="${1:-$OUTPUT}" # The one argument left overrides output filename # --------------------------------------------------------------------------- # Look though maps and find the size of the array of maps needed # #Get map limits... # min_x=9999 min_y=9999 max_x=-9999 max_y=-9999 for map in "${maps[@]}"; do # over each of the arguments # Extract the two numbers (maybe negative) from image name. read x y <<< $( echo "$map" | sed 's%.*/%%' | tr -cs '0-9-' ' ' ) #echo " -> $x $y" if (( LIMIT >= 0 )); then (( x > CENTER_X + LIMIT )) && continue (( y > CENTER_Y + LIMIT )) && continue (( x < CENTER_X - LIMIT )) && continue (( y < CENTER_Y - LIMIT )) && continue fi case "$QUARTER" in --) (( x > CENTER_X || y > CENTER_Y )) && continue ;; +-) (( x < CENTER_X || y > CENTER_Y )) && continue ;; -+) (( x > CENTER_X || y < CENTER_Y )) && continue ;; ++) (( x < CENTER_X || y < CENTER_Y )) && continue ;; ?) echo 2>& "Invalid Quater option, use -- to ++ only" esac (( min_x > x )) && min_x=$x (( min_y > y )) && min_y=$y (( max_x < x )) && max_x=$x (( max_y < y )) && max_y=$y done if (( max_x == -9999 )); then if (( LIMIT >= 0 )); then Error "No Maps Found using given center and limit" else Error "No Maps Found for given world or map path" fi fi # -------------- # # Work out output filename (-C option or not) # if [[ -v ADD_COORD ]]; then # Add the mid-coords to the output filename if [[ ! -v COORD_SET ]]; then CENTER_X=$(( (min_x+max_x)/2 )) CENTER_Y=$(( (min_y+max_y)/2 )) fi printf -v OUTPUT "%s_%+04d_%+04d_%(%F)T.jpg" $OUTPUT $CENTER_X $CENTER_Y -1 else printf -v OUTPUT "%s_%(%F)T.jpg" $OUTPUT -1 fi OUTPUT="${1:-$OUTPUT}" # The one argument left overrides output filename echo "Ranges: $min_x to $max_x , $min_y to $max_y"; echo "Area: $(( max_x - min_x +1 )) x $(( max_y - min_y +1 ))"; echo "Output: $OUTPUT" # -------------- # Collect the images in the correct order, # adding with blank images where a region map is not found. # Output a ASCII map of regions found. # # This should limit itself to the "$maps" array # but currently just uses the limits determined from that list. # # FUTURE: This currently does it as one big montage. # It probably should do it row by row. Or even in a image pyramid. # for (( y = min_y ; y <= max_y ; y++ )); do for (( x = min_x ; x <= max_x ; x++ )); do map="$x,$y.png" mask="$x,${y}_mask.png" if [[ -f "$map" ]]; then if [[ -f "$mask" ]]; then echo >&2 -n "#"; images="$images ( $map $mask -composite )" else echo >&2 -n "#"; images="$images $map" fi elif [[ -f "$mask" ]]; then echo >&2 -n " "; images="$images $mask" else echo >&2 -n " "; images="$images null:" fi done echo >&2 "" # end of row - new line done montage $images -background black \ -tile $(( max_x-min_x+1 ))x -geometry '1x1+0+0<' \ miff:- | if [ "X$OUTPUT" = "X" ] || [ "X$OUTPUT" = "Xshow:" ]; then convert - -trim +repage -resize '1000x1000>' show: else cd "$ORIGDIR" # save output relative to orginal directory convert - -trim +repage "$OUTPUT" fi