| summaryrefslogtreecommitdiff | 
diff options
| -rw-r--r-- | src/asset/www/svg/marker/blade.svg | 14 | ||||
| -rw-r--r-- | src/asset/www/svg/marker/brokenshield.svg | 185 | ||||
| -rw-r--r-- | src/asset/www/svg/marker/pawprint.svg | 44 | ||||
| -rw-r--r-- | src/battlemap/src/Struct/Navigator.elm | 2 | ||||
| -rw-r--r-- | src/battlemap/src/Struct/RangeIndicator.elm | 352 | ||||
| -rw-r--r-- | src/battlemap/www/style.css | 74 | 
6 files changed, 484 insertions, 187 deletions
| diff --git a/src/asset/www/svg/marker/blade.svg b/src/asset/www/svg/marker/blade.svg index e84734e..824a1fb 100644 --- a/src/asset/www/svg/marker/blade.svg +++ b/src/asset/www/svg/marker/blade.svg @@ -16,7 +16,7 @@     version="1.1"     id="svg8"     inkscape:version="0.92.2 5c3e80d, 2017-08-06" -   sodipodi:docname="badsword2.svg"> +   sodipodi:docname="blade.svg">    <defs       id="defs2" />    <sodipodi:namedview @@ -26,9 +26,9 @@       borderopacity="1.0"       inkscape:pageopacity="0.0"       inkscape:pageshadow="2" -     inkscape:zoom="5.6568543" -     inkscape:cx="50.958187" -     inkscape:cy="78.857285" +     inkscape:zoom="4" +     inkscape:cx="-9.8648047" +     inkscape:cy="94.093896"       inkscape:document-units="mm"       inkscape:current-layer="layer1"       showgrid="false" @@ -47,7 +47,7 @@          <dc:format>image/svg+xml</dc:format>          <dc:type             rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> -        <dc:title></dc:title> +        <dc:title />        </cc:Work>      </rdf:RDF>    </metadata> @@ -63,11 +63,11 @@       transform="translate(0,-265)"       style="display:inline">      <circle -       style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.48571736;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:170.07873535;stroke-opacity:1;paint-order:fill markers stroke" +       style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.99944496;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:170.07873535;stroke-opacity:1;paint-order:fill markers stroke"         id="path881"         cx="16"         cy="281" -       r="16" /> +       r="15.500278" />      <g         id="g829"         transform="rotate(45,13.546346,299.58838)"> diff --git a/src/asset/www/svg/marker/brokenshield.svg b/src/asset/www/svg/marker/brokenshield.svg new file mode 100644 index 0000000..9e43115 --- /dev/null +++ b/src/asset/www/svg/marker/brokenshield.svg @@ -0,0 +1,185 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg +   xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +   width="32mm" +   height="32mm" +   viewBox="0 0 32 32" +   version="1.1" +   id="svg1980" +   sodipodi:docname="brokenshield.svg" +   inkscape:version="0.92.2 5c3e80d, 2017-08-06"> +  <defs +     id="defs1974"> +    <marker +       inkscape:stockid="TriangleInS" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="TriangleInS" +       style="overflow:visible" +       inkscape:isstock="true"> +      <path +         id="path2842" +         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" +         transform="scale(-0.2)" /> +    </marker> +    <marker +       inkscape:stockid="Arrow2Mstart" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Arrow2Mstart" +       style="overflow:visible" +       inkscape:isstock="true"> +      <path +         id="path2727" +         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1" +         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " +         transform="scale(0.6) translate(0,0)" /> +    </marker> +    <marker +       inkscape:stockid="Arrow1Lend" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="marker3045" +       style="overflow:visible;" +       inkscape:isstock="true"> +      <path +         id="path3043" +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" +         transform="scale(0.8) rotate(180) translate(12.5,0)" /> +    </marker> +    <marker +       inkscape:stockid="TriangleOutS" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="TriangleOutS" +       style="overflow:visible" +       inkscape:isstock="true"> +      <path +         id="path2851" +         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" +         transform="scale(0.2)" /> +    </marker> +    <marker +       inkscape:stockid="DiamondSstart" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="DiamondSstart" +       style="overflow:visible" +       inkscape:isstock="true"> +      <path +         id="path2797" +         d="M 0,-7.0710768 L -7.0710894,0 L 0,7.0710589 L 7.0710462,0 L 0,-7.0710768 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" +         transform="scale(0.2) translate(6,0)" /> +    </marker> +    <marker +       inkscape:stockid="Arrow1Lend" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Arrow1Lend" +       style="overflow:visible;" +       inkscape:isstock="true"> +      <path +         id="path2706" +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" +         transform="scale(0.8) rotate(180) translate(12.5,0)" /> +    </marker> +  </defs> +  <sodipodi:namedview +     id="base" +     pagecolor="#ffffff" +     bordercolor="#666666" +     borderopacity="1.0" +     inkscape:pageopacity="0.0" +     inkscape:pageshadow="2" +     inkscape:zoom="1.6" +     inkscape:cx="71.986527" +     inkscape:cy="19.378828" +     inkscape:document-units="mm" +     inkscape:current-layer="layer1" +     showgrid="false" +     inkscape:pagecheckerboard="true" +     inkscape:window-width="1678" +     inkscape:window-height="1029" +     inkscape:window-x="1" +     inkscape:window-y="516" +     inkscape:window-maximized="0" +     inkscape:snap-smooth-nodes="false" +     inkscape:snap-object-midpoints="true" +     inkscape:snap-text-baseline="false" +     inkscape:measure-start="290,-40" +     inkscape:measure-end="0,0" /> +  <metadata +     id="metadata1977"> +    <rdf:RDF> +      <cc:Work +         rdf:about=""> +        <dc:format>image/svg+xml</dc:format> +        <dc:type +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> +        <dc:title></dc:title> +      </cc:Work> +    </rdf:RDF> +  </metadata> +  <g +     inkscape:label="Layer 1" +     inkscape:groupmode="layer" +     id="layer1" +     transform="translate(0,-265)"> +    <circle +       style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.99944496;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:170.07873535;stroke-opacity:1;paint-order:fill markers stroke" +       id="path881" +       cx="16.000002" +       cy="281" +       r="15.500278" /> +    <path +       style="fill:#aa0000;stroke:#000000;stroke-width:0.27668497;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" +       d="m 3.9362231,267.37059 c 5.6078188,3.22208 6.7381409,2.93483 12.0637769,0 5.367643,3.09902 7.175358,3.64572 12.063777,0 0,12.46214 -4.153352,25.27173 -12.063777,27.39135 C 8.0895779,292.64232 3.9362231,279.63317 3.9362231,267.37059 Z" +       id="path3734" +       inkscape:connector-curvature="0" +       sodipodi:nodetypes="ccccc" /> +    <path +       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.27668497;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" +       d="m 29.446962,265.27574 -2.210238,1.64823 c -2.352132,1.75419 -3.68209,2.30603 -4.969882,2.25527 -1.287791,-0.0507 -2.919041,-0.81184 -5.57513,-2.34535 l -0.6755,-0.38907 -0.684507,0.37646 c -2.643294,1.45665 -4.069953,2.10986 -5.288718,2.1364 -1.2187646,0.0265 -2.6647166,-0.54157 -5.4184148,-2.12379 l -2.0715347,-1.19248 v 2.39038 c 0,6.28748 1.0500487,12.74646 3.1649448,18.01515 2.1148961,5.26866 5.3433437,9.48526 9.9235517,10.71253 l 0.358465,0.0972 0.358467,-0.0972 c 4.569725,-1.22446 7.807222,-5.38887 9.923553,-10.63508 2.116327,-5.24621 3.164943,-11.70784 3.164943,-18.0926 z m -13.459572,4.31421 c 2.337107,1.32954 4.193781,2.27646 6.169571,2.35434 1.423989,0.0561 2.830091,-0.50135 4.30519,-1.31679 -0.251284,5.19963 -1.088346,10.34936 -2.747036,14.46113 -1.865255,4.62381 -4.53778,7.79979 -7.713313,8.83374 -3.167982,-1.03381 -5.849736,-4.25422 -7.7169175,-8.90579 -1.684291,-4.19596 -2.5340325,-9.42554 -2.7668504,-14.63764 1.6581623,0.81133 3.1414613,1.37703 4.5861969,1.34559 1.877874,-0.0408 3.605736,-0.89462 5.883159,-2.13458 z" +       id="path3734-0" +       inkscape:connector-curvature="0" /> +    <path +       sodipodi:type="star" +       style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.11299992;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:170.07873535;stroke-opacity:1;paint-order:fill markers stroke" +       id="path3029" +       sodipodi:sides="4" +       sodipodi:cx="16" +       sodipodi:cy="281" +       sodipodi:r1="10.94733" +       sodipodi:r2="5.4736652" +       sodipodi:arg1="0.80737265" +       sodipodi:arg2="1.5927708" +       inkscape:flatsided="false" +       inkscape:rounded="0" +       inkscape:randomized="0" +       d="m 23.568973,288.90915 -7.689244,-2.43681 -7.788881,2.09663 2.436808,-7.68924 -2.0966294,-7.78888 7.6892444,2.43681 7.788881,-2.09663 -2.436808,7.68924 z" +       transform="rotate(-1.52165,16,281)" /> +  </g> +  <g +     inkscape:groupmode="layer" +     id="layer3" +     inkscape:label="crack" /> +</svg> diff --git a/src/asset/www/svg/marker/pawprint.svg b/src/asset/www/svg/marker/pawprint.svg index a391da6..6fc1dee 100644 --- a/src/asset/www/svg/marker/pawprint.svg +++ b/src/asset/www/svg/marker/pawprint.svg @@ -16,7 +16,7 @@     version="1.1"     id="svg8"     inkscape:version="0.92.2 5c3e80d, 2017-08-06" -   sodipodi:docname="pawprintsi3.svg"> +   sodipodi:docname="pawprint.svg">    <defs       id="defs2" />    <sodipodi:namedview @@ -27,10 +27,10 @@       inkscape:pageopacity="0.0"       inkscape:pageshadow="2"       inkscape:zoom="3.959798" -     inkscape:cx="49.980559" -     inkscape:cy="34.26108" +     inkscape:cx="52.570979" +     inkscape:cy="25.817924"       inkscape:document-units="mm" -     inkscape:current-layer="layer2" +     inkscape:current-layer="layer1"       showgrid="false"       inkscape:window-width="1678"       inkscape:window-height="1029" @@ -46,32 +46,26 @@          <dc:format>image/svg+xml</dc:format>          <dc:type             rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> -        <dc:title></dc:title> +        <dc:title />        </cc:Work>      </rdf:RDF>    </metadata>    <g -     inkscape:groupmode="layer" -     id="layer2" -     inkscape:label="Layer 2" -     style="display:none"> -    <path -       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.40220475;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" -       d="M 0,0 V 120.94531 H 120.94531 V 0 Z m 41.615234,21.849609 a 9.7560725,13.658504 29.812375 0 1 3.529297,0.951172 9.7560725,13.658504 29.812375 0 1 1.673828,16.701172 A 9.7560725,13.658504 29.812375 0 1 31.5625,46.503906 9.7560725,13.658504 29.812375 0 1 29.888672,29.802734 9.7560725,13.658504 29.812375 0 1 41.615234,21.849609 Z m 27.908204,0.791016 a 9.7560727,13.658504 37.424364 0 1 4.417968,1.509766 9.7560727,13.658504 37.424364 0 1 -0.552734,16.77539 9.7560727,13.658504 37.424364 0 1 -16.048828,4.917969 9.7560727,13.658504 37.424364 0 1 0.552734,-16.775391 9.7560727,13.658504 37.424364 0 1 11.63086,-6.427734 z m 20.341796,19.755859 a 9.7560728,13.658504 52.866395 0 1 7.179688,3.087891 9.7560728,13.658504 52.866395 0 1 -4.998047,16.023437 9.7560728,13.658504 52.866395 0 1 -16.779297,0.466797 9.7560728,13.658504 52.866395 0 1 5,-16.023437 9.7560728,13.658504 52.866395 0 1 9.597656,-3.554688 z m -36.126953,8.597657 c 3.388294,0.06807 6.886044,1.574045 11.6875,6.615234 11.818462,12.409576 2.302984,18.878822 2.28711,30.126953 -0.01599,11.248135 -24.884546,15.716462 -26.376953,6.09375 C 39.593545,82.594601 38.70942,82.43587 26.333984,78.785156 13.958269,75.134329 22.070609,52.485868 35.875,53.351562 c 8.196383,0.513983 12.911159,-2.456913 17.863281,-2.357421 z m 37.564453,21.945312 a 9.7560729,13.658504 65.375425 0 1 8.761716,4.841797 9.7560729,13.658504 65.375425 0 1 -8.351559,14.560547 9.7560729,13.658504 65.375425 0 1 -16.482422,-3.177735 9.7560729,13.658504 65.375425 0 1 8.351562,-14.560546 9.7560729,13.658504 65.375425 0 1 7.720703,-1.664063 z" -       transform="scale(0.26458333)" -       id="rect950" -       inkscape:connector-curvature="0" /> -  </g> -  <g       inkscape:label="Layer 1"       inkscape:groupmode="layer"       id="layer1"       transform="translate(0,-265)" -     style="display:inline" -     sodipodi:insensitive="true"> +     style="display:inline"> +    <circle +       style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.99944496;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:170.07873535;stroke-opacity:1;paint-order:fill markers stroke" +       id="path881" +       cx="16" +       cy="281" +       r="15.500278" />      <g         id="g947" -       transform="matrix(1.100568,1.1037005,-1.1037005,1.100568,323.12892,-47.049468)"> +       transform="matrix(1.100568,1.1037005,-1.1037005,1.100568,323.12892,-47.049468)" +       style="fill:#ffffff">        <ellipse           transform="rotate(-15.269049)"           ry="2.3185458" @@ -79,7 +73,7 @@           cy="278.6438"           cx="-71.76931"           id="path815" -         style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.37077442;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> +         style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.37077442;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />        <use           transform="rotate(7.6119885,30.142915,310.98335)"           height="100%" @@ -88,7 +82,7 @@           xlink:href="#path815"           y="0"           x="0" -         style="fill:#000000;stroke:none;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +         style="fill:#ffffff;stroke:none;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />        <use           transform="rotate(15.442031,10.627428,301.73172)"           height="100%" @@ -97,7 +91,7 @@           xlink:href="#use817"           y="0"           x="0" -         style="fill:#000000;stroke:none;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +         style="fill:#ffffff;stroke:none;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />        <use           transform="rotate(12.50903,-1.4011846,303.06723)"           height="100%" @@ -106,13 +100,13 @@           xlink:href="#use819"           y="0"           x="0" -         style="fill:#000000;stroke:none;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +         style="fill:#ffffff;stroke:none;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />        <path           sodipodi:nodetypes="zzszzz"           inkscape:connector-curvature="0"           id="path823"           d="m 6.0960684,290.24753 c -1.7586733,1.55556 -0.00849,5.24544 1.9137203,4.19544 1.9221629,-1.04998 2.0472473,-1.13722 3.6066263,4e-5 1.335557,0.974 3.77909,-2.55093 2.428952,-3.90107 -1.350138,-1.35014 -0.987055,-3.26954 -3.895296,-3.33636 -2.9082424,-0.0667 -2.2953294,1.48638 -4.0540026,3.04195 z" -         style="fill:#000000;stroke:none;stroke-width:0.37077442;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +         style="fill:#ffffff;stroke:none;stroke-width:0.37077442;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />      </g>    </g>  </svg> diff --git a/src/battlemap/src/Struct/Navigator.elm b/src/battlemap/src/Struct/Navigator.elm index 1b3f170..46ad92c 100644 --- a/src/battlemap/src/Struct/Navigator.elm +++ b/src/battlemap/src/Struct/Navigator.elm @@ -80,7 +80,7 @@ new start_loc mov_dist atk_dist def_dist cost_fun =              start_loc              mov_dist              atk_dist -            0 +            def_dist              (cost_fun)           ),        cost_fun = cost_fun diff --git a/src/battlemap/src/Struct/RangeIndicator.elm b/src/battlemap/src/Struct/RangeIndicator.elm index 06b34ec..2b70ecd 100644 --- a/src/battlemap/src/Struct/RangeIndicator.elm +++ b/src/battlemap/src/Struct/RangeIndicator.elm @@ -6,8 +6,6 @@ module Struct.RangeIndicator exposing        get_path     ) --- FIXME: This module is still too much of a mess... -  -- Elm -------------------------------------------------------------------------  import Dict  import List @@ -31,6 +29,19 @@ type alias Type =        marker: Struct.Marker.Type     } +type alias SearchParameters = +   { +      maximum_distance: Int, +      maximum_attack_range: Int, +      minimum_defense_range: Int, +      cost_function: (Struct.Location.Type -> Int) +   } + +type alias LocatedIndicator = +   { +      location_ref: Struct.Location.Ref, +      indicator: Type +   }  --------------------------------------------------------------------------------  -- LOCAL -----------------------------------------------------------------------  -------------------------------------------------------------------------------- @@ -38,186 +49,238 @@ get_closest : (        Int ->        Struct.Location.Ref ->        Type -> -      (Struct.Location.Ref, Type) -> -      (Struct.Location.Ref, Type) +      LocatedIndicator -> +      LocatedIndicator     ) -get_closest dist ref indicator (prev_ref, prev_indicator) = -   if +get_closest max_dist ref indicator current_best = +   if (is_closer max_dist indicator current_best.indicator) +   then +      { +         location_ref = ref, +         indicator = indicator +      } +   else +      current_best + +is_closer : Int -> Type -> Type -> Bool +is_closer max_dist candidate current =     ( -      (indicator.distance < prev_indicator.distance) +      -- It's closer when moving +      (candidate.distance < current.distance)        ||        ( -         (indicator.distance > dist) -         && (prev_indicator.distance > dist) -         && (indicator.atk_range < prev_indicator.atk_range) +         -- Or neither are reachable by moving, +         (max_dist <= candidate.distance) +         && (max_dist <= current.distance) +         -- but the new one is closer when attacking. +         && (candidate.atk_range < current.atk_range)        )     ) -   then -      (ref, indicator) -   else -      (prev_ref, prev_indicator) -is_closer : Int -> Int -> Type -> Bool -is_closer new_dist new_range neighbor = +generate_neighbor : ( +      SearchParameters -> +      Struct.Location.Type -> +      Struct.Direction.Type -> +      Type -> +      (Int, Type) +   ) +generate_neighbor search_params neighbor_loc dir src_indicator = +   let +      node_cost = (search_params.cost_function neighbor_loc) +      new_dist = (src_indicator.distance + node_cost) +      new_atk_range = (src_indicator.atk_range + 1) +      new_true_range = (src_indicator.true_range + 1) +      can_defend = (new_true_range > search_params.minimum_defense_range) +   in +      if (new_dist > search_params.maximum_distance) +      then +         ( +            node_cost, +            { +               distance = (search_params.maximum_distance + 1), +               atk_range = new_atk_range, +               true_range = new_true_range, +               path = (dir :: src_indicator.path), +               marker = +                  if (can_defend) +                  then +                     Struct.Marker.CanAttackCanDefend +                  else +                     Struct.Marker.CanAttackCantDefend +            } +         ) +      else +         ( +            node_cost, +            { +               distance = new_dist, +               atk_range = 0, +               true_range = new_true_range, +               path = (dir :: src_indicator.path), +               marker = +                  if (can_defend) +                  then +                     Struct.Marker.CanGoToCanDefend +                  else +                     Struct.Marker.CanGoToCantDefend +            } +         ) + +candidate_is_acceptable : (SearchParameters -> Int -> Type -> Bool) +candidate_is_acceptable search_params cost candidate = +   (cost /= Constants.Movement.cost_when_out_of_bounds) +   &&     ( -      (new_dist < neighbor.distance) +      (candidate.distance <= search_params.maximum_distance)        || -      ( -         (neighbor.distance > new_dist) -         && (new_range < neighbor.atk_range) -      ) +      (candidate.atk_range <= search_params.maximum_attack_range)     ) +candidate_is_an_improvement : ( +      SearchParameters -> +      Struct.Location.Ref -> +      Type -> +      (Dict.Dict Struct.Location.Ref Type) -> +      Bool +   ) +candidate_is_an_improvement search_params loc_ref candidate alternatives = +   case (Dict.get loc_ref alternatives) of +      (Just alternative) -> +         (is_closer search_params.maximum_distance candidate alternative) + +      Nothing -> +         True  handle_neighbors : ( -      Type -> -      Struct.Location.Type -> -      Int -> -      Int -> -      Int -> +      LocatedIndicator ->        (Dict.Dict Struct.Location.Ref Type) -> -      (Struct.Location.Type -> Int) -> +      SearchParameters ->        Struct.Direction.Type ->        (Dict.Dict Struct.Location.Ref Type) ->        (Dict.Dict Struct.Location.Ref Type)     ) -handle_neighbors -   src_indicator src_loc -   dist -   atk_range def_range -   results cost_fun dir rem = +handle_neighbors src results search_params dir remaining =     let +      src_loc = (Struct.Location.from_ref src.location_ref)        neighbor_loc = (Struct.Location.neighbor dir src_loc) +      neighbor_loc_ref = (Struct.Location.get_ref neighbor_loc)     in -      case (Dict.get (Struct.Location.get_ref neighbor_loc) results) of -         (Just _) -> rem +      case (Dict.get neighbor_loc_ref results) of +         (Just _) -> +            -- A minimal path for this location has already been found +            remaining           Nothing ->              let -               node_cost = (cost_fun neighbor_loc) -               new_dist = (src_indicator.distance + node_cost) -               new_atk_range = (src_indicator.atk_range + 1) -               new_true_range = (src_indicator.true_range + 1) -               can_defend = (new_true_range >= def_range) +               (candidate_cost, candidate) = +                  (generate_neighbor +                     search_params +                     neighbor_loc +                     dir +                     src.indicator +                  )              in                 if -                  ( -                     ( -                        case -                           (Dict.get -                              (Struct.Location.get_ref neighbor_loc) -                              rem -                           ) -                        of -                           (Just neighbor) -> -                              (is_closer new_dist new_atk_range neighbor) - -                           Nothing -> -                              True -                     ) -                     && -                     (node_cost /= Constants.Movement.cost_when_out_of_bounds) -                     && -                     ( -                        (new_dist <= dist) -                        || -                        (new_atk_range <= atk_range) -                     ) +               ( +                  (candidate_is_acceptable +                     search_params +                     candidate_cost +                     candidate                    ) -               then -                  (Dict.insert -                     (Struct.Location.get_ref neighbor_loc) -                     ( -                        if (new_dist > dist) -                        then -                           { -                              distance = (dist + 1), -                              atk_range = new_atk_range, -                              true_range = new_true_range, -                              path = (dir :: src_indicator.path), -                              marker = -                                 if (can_defend) -                                 then -                                    Struct.Marker.CanAttackCanDefend -                                 else -                                    Struct.Marker.CanAttackCantDefend -                           } -                        else -                           { -                              distance = new_dist, -                              atk_range = 0, -                              true_range = new_true_range, -                              path = (dir :: src_indicator.path), -                              marker = -                                 if (can_defend) -                                 then -                                    Struct.Marker.CanGoToCanDefend -                                 else -                                    Struct.Marker.CanGoToCantDefend -                           } -                     ) -                     rem +                  && +                  (candidate_is_an_improvement +                     search_params +                     neighbor_loc_ref +                     candidate +                     remaining                    ) +               ) +               then +                  (Dict.insert neighbor_loc_ref candidate remaining)                 else -                  rem +                  remaining + +find_closest_in : ( +      SearchParameters -> +      (Dict.Dict Struct.Location.Ref Type) -> +      LocatedIndicator +   ) +find_closest_in search_params remaining = +   (Dict.foldl +      (get_closest search_params.maximum_distance) +      { +         location_ref = (-1, -1), +         indicator = +            { +               distance = Constants.Movement.cost_when_out_of_bounds, +               path = [], +               atk_range = Constants.Movement.cost_when_out_of_bounds, +               true_range = Constants.Movement.cost_when_out_of_bounds, +               marker = Struct.Marker.CanAttackCanDefend +            } +      } +      remaining +   ) + +resolve_marker_type : SearchParameters -> Type -> Type +resolve_marker_type search_params indicator = +   {indicator | +      marker = +         case +            ( +               (indicator.atk_range > 0), +               (indicator.true_range <= search_params.minimum_defense_range) +            ) +         of +            (True, True) -> Struct.Marker.CanAttackCantDefend +            (True, False) -> Struct.Marker.CanAttackCanDefend +            (False, True) -> Struct.Marker.CanGoToCantDefend +            (False, False) -> Struct.Marker.CanGoToCanDefend +   } + +insert_in_dictionary : ( +      LocatedIndicator -> +      (Dict.Dict Struct.Location.Ref Type) -> +      (Dict.Dict Struct.Location.Ref Type) +   ) +insert_in_dictionary located_indicator dict = +   (Dict.insert +      located_indicator.location_ref +      located_indicator.indicator +      dict +   )  search : (        (Dict.Dict Struct.Location.Ref Type) ->        (Dict.Dict Struct.Location.Ref Type) -> -      Int -> -      Int -> -      Int -> -      (Struct.Location.Type -> Int) -> +      SearchParameters ->        (Dict.Dict Struct.Location.Ref Type)     ) -search result remaining dist atk_range def_range cost_fun = +search result remaining search_params =     if (Dict.isEmpty remaining)     then        result     else        let -         (min_loc_ref, min) = -            (Dict.foldl -               (get_closest dist) -               ( -                  (-1,-1), -                  { -                     distance = Constants.Movement.cost_when_out_of_bounds, -                     path = [], -                     atk_range = Constants.Movement.cost_when_out_of_bounds, -                     true_range = Constants.Movement.cost_when_out_of_bounds, -                     marker = Struct.Marker.CanAttackCanDefend -                  } -               ) -               remaining -            ) +         closest_located_indicator = (find_closest_in search_params remaining) +         finalized_clos_loc_ind = +            {closest_located_indicator| +               indicator = +                  (resolve_marker_type +                     search_params +                     closest_located_indicator.indicator +                  ) +            }        in           (search -            (Dict.insert -               min_loc_ref -               {min | -                  marker = -                     case -                        ((min.atk_range > 0), (min.true_range <= def_range)) -                     of -                        (True, True) -> Struct.Marker.CanAttackCantDefend -                        (True, False) -> Struct.Marker.CanAttackCanDefend -                        (False, True) -> Struct.Marker.CanGoToCantDefend -                        (False, False) -> Struct.Marker.CanGoToCanDefend -               } -               result -            ) +            (insert_in_dictionary finalized_clos_loc_ind result)              (List.foldl                 (handle_neighbors -                  min -                  (Struct.Location.from_ref min_loc_ref) -                  dist -                  atk_range -                  def_range +                  finalized_clos_loc_ind                    result -                  (cost_fun) +                  search_params                 ) -               (Dict.remove min_loc_ref remaining) +               (Dict.remove finalized_clos_loc_ind.location_ref remaining)                 [                    Struct.Direction.Left,                    Struct.Direction.Right, @@ -225,10 +288,7 @@ search result remaining dist atk_range def_range cost_fun =                    Struct.Direction.Down                 ]              ) -            dist -            atk_range -            def_range -            (cost_fun) +            search_params           )  -------------------------------------------------------------------------------- @@ -242,7 +302,7 @@ generate : (        (Struct.Location.Type -> Int) ->        (Dict.Dict Struct.Location.Ref Type)     ) -generate location dist atk_range def_range cost_fun = +generate location max_dist atk_range def_range cost_fun =     (search        Dict.empty        (Dict.insert @@ -261,10 +321,12 @@ generate location dist atk_range def_range cost_fun =           }           Dict.empty        ) -      dist -      atk_range -      def_range -      (cost_fun) +      { +         maximum_distance = max_dist, +         maximum_attack_range = atk_range, +         minimum_defense_range = def_range, +         cost_function = (cost_fun) +      }     )  get_marker : Type -> Struct.Marker.Type diff --git a/src/battlemap/www/style.css b/src/battlemap/www/style.css index 04bce9a..4b1db1b 100644 --- a/src/battlemap/www/style.css +++ b/src/battlemap/www/style.css @@ -463,7 +463,6 @@  .battlemap-marker-icon     {z-index: 2;}  .battlemap-path-icon-above-markers {z-index: 3;}  .battlemap-character-icon  {z-index: 4;} -.battlemap-marker-icon.battlemap-navigator-non-interactive     {z-index: 5;}  .battlemap-marker-icon,  .battlemap-character-icon, @@ -549,29 +548,31 @@     opacity: 0.3;     transition: opacity 0.3s ease-out;  } +  .battlemap-can-go-to-cant-defend-marker.battlemap-navigator-interactive  {     background:        repeating-linear-gradient(          -55deg, -        rgba(255,255,255,0.3), -        rgba(255,255,255,0.3) 3px, -        rgba(0,0,0,0.3) 3px, -        rgba(0,0,0,0.3) 7px +        rgb(255,255,255), +        rgb(255,255,255) 3px, +        rgba(0,0,0,0) 3px, +        rgba(0,0,0,0) 7px        );     opacity: 0.3;     transition: opacity 0.3s ease-out;  } -.battlemap-can-go-to-can-defend-marker.battlemap-navigator-interactive:hover +.battlemap-can-go-to-can-defend-marker.battlemap-navigator-interactive:hover, +.battlemap-can-go-to-cant-defend-marker.battlemap-navigator-interactive:hover  { -   background-color: rgba(255, 255, 255, 0.9); -   opacity: 1; +   opacity: 0.9;  }  .battlemap-can-attack-can-defend-marker.battlemap-navigator-interactive  { -   background-color:rgba(0,0,0,0.7); +   background-color: #000; +   opacity: 0.7;     width: 28px;     /*min-width: 28px;     max-width: 28px;*/ @@ -580,14 +581,69 @@     border-radius: 0;  } +.battlemap-can-attack-cant-defend-marker.battlemap-navigator-interactive +{ +   background: +      repeating-linear-gradient( +        -55deg, +        rgba(255,255,255,0), +        rgba(255,255,255,0) 3px, +        rgb(0,0,0) 3px, +        rgb(0,0,0) 7px +      ); +   width: 28px; +   /*min-width: 28px; +   max-width: 28px;*/ +   opacity: 0.7; +   height: 28px; +   margin: 2px 0 0 2px; +   border-radius: 0; +} +  .battlemap-can-attack-can-defend-marker.battlemap-navigator-non-interactive  {     background-image: url(/asset/svg/marker/blade.svg); +}  + +.battlemap-can-attack-cant-defend-marker.battlemap-navigator-non-interactive +{ +   background-image: +      url(/asset/svg/marker/blade.svg), +      url(/asset/svg/marker/brokenshield.svg); +} + +.battlemap-can-go-to-cant-defend-marker.battlemap-navigator-non-interactive +{ +   background-image: +      url(/asset/svg/marker/pawprint.svg), +      url(/asset/svg/marker/brokenshield.svg); +} + +.battlemap-can-attack-cant-defend-marker.battlemap-navigator-non-interactive, +.battlemap-can-go-to-cant-defend-marker.battlemap-navigator-non-interactive +{ +   width: 24px; +   height: 24px; +   background-position: top left, bottom right; +   background-size: 50%, 50%; +   background-repeat: no-repeat, no-repeat; +   margin: 2px;  }  .battlemap-can-go-to-can-defend-marker.battlemap-navigator-non-interactive  {     background-image: url(/asset/svg/marker/pawprint.svg); +} + +.battlemap-can-attack-can-defend-marker.battlemap-navigator-non-interactive, +.battlemap-can-attack-cant-defend-marker..battlemap-navigator-non-interactive +{ +   z-index: 5; +} + +.battlemap-can-go-to-can-defend-marker, +.battlemap-can-go-to-cant-defend-marker +{     z-index: 3;  } | 


