1
0
Fork 0

Added jobs in dockyards (WIP)

This commit is contained in:
Michaël Lemaire 2017-07-07 00:55:29 +02:00
parent 993ed0e897
commit 0feba35db0
23 changed files with 940 additions and 55 deletions

View file

@ -811,8 +811,8 @@
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter7229-3"
x="-0.2"
y="-0.2"
x="-0.25"
y="-0.25"
height="1.5"
width="1.5">
<feFlood
@ -872,6 +872,237 @@
fx="349.2796"
fy="150.05988"
r="3.9959407" />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath5802">
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/options/background.png"
style="display:inline;fill:#2c353d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9375px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7512);enable-background:new"
d="M 475.82605,190.2261 H 1444.174 l -93.4957,699.5478 H 569.3217 Z"
id="path5804"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
transform="matrix(0.34038154,0,0,0.34038154,19.662314,-53.825672)" />
</clipPath>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter7193">
<feFlood
flood-opacity="1"
flood-color="rgb(255,255,255)"
result="flood"
id="feFlood7183" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite7185" />
<feGaussianBlur
in="composite1"
stdDeviation="0.4"
result="blur"
id="feGaussianBlur7187" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset7189" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite7191" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter6138">
<feFlood
flood-opacity="1"
flood-color="rgb(255,255,255)"
result="flood"
id="feFlood6128" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite6130" />
<feGaussianBlur
in="composite1"
stdDeviation="0.4"
result="blur"
id="feGaussianBlur6132" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset6134" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite6136" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Dialog shadow"
id="filter7512">
<feFlood
flood-opacity="1"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood7502" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite7504" />
<feGaussianBlur
in="composite1"
stdDeviation="33.649999999999999"
result="blur"
id="feGaussianBlur7506" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset7508" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite7510" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter5500-2"
x="-0.2"
y="-0.2"
width="1.4"
height="1.4">
<feFlood
flood-opacity="0.556863"
flood-color="rgb(255,255,255)"
result="flood"
id="feFlood5490-9" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite5492-1" />
<feGaussianBlur
in="composite1"
stdDeviation="1.1"
result="blur"
id="feGaussianBlur5494-2" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset5496-7" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite5498-0" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter5500-3"
x="-0.20000000000000001"
y="-0.20000000000000001"
width="1.3999999999999999"
height="1.3999999999999999">
<feFlood
flood-opacity="0.556863"
flood-color="rgb(255,255,255)"
result="flood"
id="feFlood5490-6" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite5492-0" />
<feGaussianBlur
in="composite1"
stdDeviation="1.1"
result="blur"
id="feGaussianBlur5494-6" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset5496-2" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite5498-6" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter6297"
x="-0.20000000000000001"
y="-0.20000000000000001"
width="1.3999999999999999"
height="1.3999999999999999">
<feFlood
flood-opacity="0.556863"
flood-color="rgb(255,255,255)"
result="flood"
id="feFlood6287" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite6289" />
<feGaussianBlur
in="composite1"
stdDeviation="1.1"
result="blur"
id="feGaussianBlur6291" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset6293" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite6295" />
</filter>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter6390"
x="-0.0936"
width="1.1872"
y="-0.0936"
height="1.1872">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="1.1866562"
id="feGaussianBlur6392" />
</filter>
</defs>
<sodipodi:namedview
id="base"
@ -880,11 +1111,11 @@
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="2.0000001"
inkscape:cx="221.23289"
inkscape:cy="353.88524"
inkscape:zoom="0.70710682"
inkscape:cx="728.12591"
inkscape:cy="574.187"
inkscape:document-units="px"
inkscape:current-layer="g7264"
inkscape:current-layer="g6210"
showgrid="false"
units="px"
inkscape:snap-bbox="true"
@ -893,8 +1124,10 @@
showguides="false"
inkscape:bbox-nodes="true"
inkscape:snap-page="true"
inkscape:snap-global="true"
inkscape:snap-object-midpoints="true">
inkscape:snap-global="false"
inkscape:snap-object-midpoints="true"
inkscape:measure-start="551.543,453.963"
inkscape:measure-end="1261.48,449.72">
<sodipodi:guide
position="0,0"
orientation="0,1920"
@ -1979,4 +2212,400 @@
style="fill:#43535c;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.23345587px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="Mission dialog"
style="display:inline">
<g
id="g6210"
transform="translate(-4.1823501,30.369099)">
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/common/dialog.png"
style="display:inline;fill:#2c353d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9375px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7512);enable-background:new"
d="M 475.82605,190.2261 H 1444.174 l -93.4957,699.5478 H 569.3217 Z"
id="rect4931"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
transform="matrix(0.34038154,0,0,0.34038154,-68.583942,-71.300136)" />
<g
clip-path="url(#clipPath5802)"
inkscape:export-ydpi="91.800003"
inkscape:export-xdpi="91.800003"
inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/common/dialog-close1.png"
id="g5454"
style="display:inline;opacity:1"
transform="translate(-88.246252,-17.474463)">
<circle
style="fill:#151c22;fill-opacity:1;stroke:#c1c1c1;stroke-width:0.79374999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7193)"
id="path7854"
cx="508"
cy="11.249985"
r="20.847025" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.58333397px;line-height:6.61458349px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';letter-spacing:0px;word-spacing:0px;fill:#d5c5ae;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7193)"
x="496.83798"
y="22.792192"
id="text7862"><tspan
sodipodi:role="line"
id="tspan7860"
x="496.83798"
y="22.792192"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#d5c5ae;fill-opacity:1;stroke-width:0.26458335px">X</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b8d2f1;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="223.79375"
y="20.359943"
id="text6214"><tspan
sodipodi:role="line"
id="tspan6212"
x="223.79375"
y="20.359943"
style="fill:#b8d2f1;fill-opacity:1;stroke-width:0.26458335px">Active jobs</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b8d2f1;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="213.62073"
y="116.95998"
id="text6218"><tspan
sodipodi:role="line"
id="tspan6216"
x="213.62073"
y="116.95998"
style="fill:#b8d2f1;fill-opacity:1;stroke-width:0.26458335px">Proposed jobs</tspan></text>
<g
id="g6630"
transform="translate(0,7.4083337)">
<use
transform="translate(0,23.881537)"
height="100%"
width="100%"
id="use6334"
inkscape:transform-center-y="-0.66101504"
xlink:href="#use6271"
y="0"
x="0" />
<g
id="g6499">
<text
id="text6338"
y="51.764362"
x="152.35658"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:7.76111126px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px"
y="51.764362"
x="152.35658"
id="tspan6336"
sodipodi:role="line">Escort a merchant transport to Rhinard</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05555582px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="152.35658"
y="61.289371"
id="text6342"><tspan
sodipodi:role="line"
id="tspan6340"
x="152.35658"
y="61.289371"
style="font-size:7.05555582px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px">Reward : 500 zotys</tspan></text>
</g>
</g>
<g
id="g6622"
transform="translate(0,7.4083337)">
<use
transform="translate(121.04306,-195.15429)"
height="100%"
width="100%"
id="use6271"
inkscape:transform-center-y="-0.66101504"
xlink:href="#path7197"
y="0"
x="0"
style="display:inline" />
<g
id="g6493">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="152.35658"
y="27.882824"
id="text6332"><tspan
sodipodi:role="line"
id="tspan6330"
x="152.35658"
y="27.882824"
style="font-size:7.76111126px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px">Deliver an item to the FTC contact in Suburbia</tspan></text>
<text
id="text6364"
y="37.937"
x="152.35658"
style="font-style:normal;font-weight:normal;font-size:7.05555582px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:7.05555582px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px"
y="37.937"
x="152.35658"
id="tspan6362"
sodipodi:role="line">Reward : Legendary SubMunition Missile Mk4</tspan></text>
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#c57147;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="195.37274"
y="84.18927"
id="text6370"><tspan
sodipodi:role="line"
id="tspan6368"
x="195.37274"
y="84.18927"
style="font-size:8.46666718px;fill:#c57147;fill-opacity:1;stroke-width:0.26458335px">Cannot accept more missions</tspan></text>
<g
id="g6485"
transform="translate(-14.81667,12.026318)">
<g
transform="matrix(0.21520643,0.21520643,-0.21520643,0.21520643,286.3185,-60.540215)"
id="g6378">
<use
transform="matrix(2.3233506,-2.3233506,2.3233506,2.3233506,-525.09999,803.63525)"
x="0"
y="0"
xlink:href="#path6571"
id="use6579"
width="100%"
height="100%" />
<rect
y="23.390965"
x="351.41891"
height="7.4835463"
width="35.546844"
style="fill:#8ab4e7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7229-3)"
id="use6398"
transform="rotate(90,370.99631,25.421645)" />
</g>
<text
inkscape:transform-center-y="3.5546847"
inkscape:transform-center-x="-0.74835467"
id="text6396"
y="27.506914"
x="372.11609"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:7.05555582px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px"
y="27.506914"
x="372.11609"
id="tspan6394"
sodipodi:role="line">Cancel</tspan></text>
<path
inkscape:connector-curvature="0"
id="path6400"
d="m 351.98078,24.297867 v 7.276041 l 50.40313,1e-6"
style="fill:none;fill-rule:evenodd;stroke:#8ab4e7;stroke-width:0.5291667;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<use
x="0"
y="0"
xlink:href="#g6485"
id="use6487"
width="100%"
height="100%"
transform="translate(0,23.881537)"
inkscape:export-filename="/tmp/export.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<g
id="g6523"
transform="translate(0,7.4083337)">
<use
style="display:inline"
x="0"
y="0"
xlink:href="#path7197"
inkscape:transform-center-y="-0.66101504"
id="use6501"
width="100%"
height="100%"
transform="translate(121.04306,-96.199953)" />
<g
transform="translate(0,98.954178)"
id="g6511">
<text
id="text6505"
y="27.882824"
x="152.35658"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:7.76111126px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px"
y="27.882824"
x="152.35658"
id="tspan6503"
sodipodi:role="line">Deliver an item to the FTC contact in Suburbia</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05555582px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="152.35658"
y="37.937"
id="text6509"><tspan
sodipodi:role="line"
id="tspan6507"
x="152.35658"
y="37.937"
style="font-size:7.05555582px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px">Reward : Legendary SubMunition Missile Mk4</tspan></text>
</g>
</g>
<g
id="g6537"
transform="translate(0,34.925014)">
<use
transform="translate(121.04306,-96.199953)"
height="100%"
width="100%"
id="use6525"
inkscape:transform-center-y="-0.66101504"
xlink:href="#path7197"
y="0"
x="0"
style="display:inline" />
<g
id="g6535"
transform="translate(0,98.954178)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="152.35658"
y="27.882824"
id="text6529"><tspan
sodipodi:role="line"
id="tspan6527"
x="152.35658"
y="27.882824"
style="font-size:7.76111126px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px">Deliver an item to the FTC contact in Suburbia</tspan></text>
<text
id="text6533"
y="37.937"
x="152.35658"
style="font-style:normal;font-weight:normal;font-size:7.05555582px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:7.05555582px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px"
y="37.937"
x="152.35658"
id="tspan6531"
sodipodi:role="line">Reward : Legendary SubMunition Missile Mk4</tspan></text>
</g>
</g>
<g
transform="translate(0,62.441675)"
id="g6551">
<use
style="display:inline"
x="0"
y="0"
xlink:href="#path7197"
inkscape:transform-center-y="-0.66101504"
id="use6539"
width="100%"
height="100%"
transform="translate(121.04306,-96.199953)" />
<g
transform="translate(0,98.954178)"
id="g6549">
<text
id="text6543"
y="27.882824"
x="152.35658"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:7.76111126px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px"
y="27.882824"
x="152.35658"
id="tspan6541"
sodipodi:role="line">Deliver an item to the FTC contact in Suburbia</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.05555582px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="152.35658"
y="37.937"
id="text6547"><tspan
sodipodi:role="line"
id="tspan6545"
x="152.35658"
y="37.937"
style="font-size:7.05555582px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px">Reward : Legendary SubMunition Missile Mk4</tspan></text>
</g>
</g>
<g
transform="translate(-14.81667,111.42406)"
id="g6565"
inkscape:export-filename="/tmp/export.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.70000076px;line-height:6.61458349px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d2e1f3;fill-opacity:1;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="371.05774"
y="27.506914"
id="text6561"
inkscape:transform-center-x="-0.74835467"
inkscape:transform-center-y="3.5546847"><tspan
sodipodi:role="line"
id="tspan6559"
x="371.05774"
y="27.506914"
style="font-size:7.05555582px;fill:#d2e1f3;fill-opacity:1;stroke-width:0.26458335px">Accept</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#8ab4e7;stroke-width:0.5291667;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 351.98078,24.297867 v 7.276041 l 50.40313,1e-6"
id="path6563"
inkscape:connector-curvature="0" />
<g
id="g6608">
<circle
r="4.490128"
cy="24.61265"
cx="360.34225"
id="path6571"
style="fill:#222932;fill-opacity:1;fill-rule:evenodd;stroke:#8ab4e7;stroke-width:0.5291667;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<path
sodipodi:type="star"
style="fill:#8ab4e7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1217779px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path6596"
sodipodi:sides="3"
sodipodi:cx="356.96808"
sodipodi:cy="24.61265"
sodipodi:r1="1.918968"
sodipodi:r2="0.01918968"
sodipodi:arg1="0"
sodipodi:arg2="1.0471976"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 358.88705,24.61265 -2.87846,1.661875 v -3.32375 z"
inkscape:transform-center-x="-0.42217421"
inkscape:transform-center-y="1.2619461e-06" />
</g>
<use
x="0"
y="0"
xlink:href="#g6565"
id="use6567"
width="100%"
height="100%"
transform="translate(0,27.516676)" />
<use
x="0"
y="0"
xlink:href="#g6565"
id="use6569"
width="100%"
height="100%"
transform="translate(0,55.033337)" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 388 KiB

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -8,7 +8,7 @@ module TS.SpaceTac {
private random: RandomGenerator;
constructor(choices: string[], random: RandomGenerator = new RandomGenerator()) {
this.choices = choices.slice(0);
this.choices = acopy(choices);
this.random = random;
}

View file

@ -31,5 +31,41 @@ module TS.SpaceTac.Specs {
expect(shop.stock).toEqual([equ1, equ2]);
expect(fleet.credits).toEqual(1000);
});
it("generates secondary missions", function () {
let universe = new Universe();
universe.generate(4);
let start = universe.getStartLocation();
let shop = new Shop();
expect((<any>shop).missions.length).toBe(0);
let result = shop.getMissions(start, 4);
expect(result.length).toBe(4);
expect((<any>shop).missions.length).toBe(4);
let oresult = shop.getMissions(start, 4);
expect(oresult).toEqual(result);
result.forEach(mission => {
expect(mission.main).toBe(false);
});
});
it("assigns missions to a fleet", function () {
let shop = new Shop();
let player = new Player();
let mission = new Mission(new Universe());
(<any>shop).missions = [mission];
expect(shop.getMissions(new StarLocation(), 1)).toEqual([mission]);
expect(player.missions.secondary).toEqual([]);
shop.acceptMission(mission, player);
expect((<any>shop).missions).toEqual([]);
expect(player.missions.secondary).toEqual([mission]);
expect(mission.fleet).toBe(player.fleet);
});
});
}

View file

@ -15,6 +15,9 @@ module TS.SpaceTac {
// Random generator
private random: RandomGenerator
// Available missions
private missions: Mission[] = []
constructor(level = 1, stock: Equipment[] = [], count = 40) {
this.level = level;
this.stock = stock;
@ -98,5 +101,33 @@ module TS.SpaceTac {
return false;
}
}
/**
* Get a list of available secondary missions
*/
getMissions(around: StarLocation, max_count = 3): Mission[] {
while (this.missions.length < max_count) {
let generator = new MissionGenerator(around.star.universe, around.star.level, around, this.random);
let mission = generator.generate();
this.missions.push(mission);
}
return this.missions;
}
/**
* Assign a mission to a fleet
*
* Returns true on success
*/
acceptMission(mission: Mission, player: Player): boolean {
if (player.missions.secondary.length < 2 && remove(this.missions, mission)) {
mission.fleet = player.fleet;
add(player.missions.secondary, mission);
return true;
} else {
return false;
}
}
}
}

View file

@ -2,10 +2,10 @@ module TS.SpaceTac.Specs {
describe("Star", () => {
it("lists links to other stars", () => {
var universe = new Universe();
universe.stars.push(new Star(universe, 0, 0));
universe.stars.push(new Star(universe, 1, 0));
universe.stars.push(new Star(universe, 0, 1));
universe.stars.push(new Star(universe, 1, 1));
universe.stars.push(new Star(universe, 0, 0, "Star A"));
universe.stars.push(new Star(universe, 1, 0, "Star B"));
universe.stars.push(new Star(universe, 0, 1, "Star C"));
universe.stars.push(new Star(universe, 1, 1, "Star D"));
universe.addLink(universe.stars[0], universe.stars[1]);
universe.addLink(universe.stars[0], universe.stars[3]);
@ -26,6 +26,11 @@ module TS.SpaceTac.Specs {
expect(universe.stars[3].getLinkTo(universe.stars[0])).toEqual(universe.starlinks[1]);
expect(universe.stars[3].getLinkTo(universe.stars[1])).toBeNull();
expect(universe.stars[3].getLinkTo(universe.stars[2])).toBeNull();
let neighbors = universe.stars[0].getNeighbors();
expect(neighbors.length).toBe(2);
expect(neighbors).toContain(universe.stars[1]);
expect(neighbors).toContain(universe.stars[3]);
});
});
}

View file

@ -89,6 +89,14 @@ module TS.SpaceTac {
return `Star ${this.name}`;
}
/**
* Add a location of interest
*/
addLocation(type: StarLocationType): StarLocation {
let result = new StarLocation(this, type);
return result;
}
// Get the distance to another star
getDistanceTo(star: Star): number {
var dx = this.x - star.x;
@ -159,6 +167,13 @@ module TS.SpaceTac {
return result;
}
/**
* Get the neighboring star systems (single jump accessible)
*/
getNeighbors(): Star[] {
return nna(this.getLinks().map(link => link.getPeer(this)));
}
// Check if a location is far enough from all other ones
private checkMinDistance(loc: StarLocation, others: StarLocation[]): boolean {
return others.every((iloc: StarLocation): boolean => {

View file

@ -13,10 +13,31 @@ module TS.SpaceTac {
radius = 5
// Source of randomness
random = RandomGenerator.global;
random = RandomGenerator.global
// Generates a universe, with star systems and such
/**
* Add a single star
*/
addStar(level = 1, name?: string): Star {
let result = new Star(this, 0, 0, name || `Star ${this.stars.length + 1}`);
result.level = level;
this.stars.push(result);
return result;
}
/**
* Generates a random universe, with star systems and locations of interest
*
* This will also :
* - create a network of jump links between star systems
* - add random shops
* - define a progressive gradient of enemy levels
*/
generate(starcount = 50): void {
if (starcount < 4) {
starcount = 4;
}
while (this.stars.length == 0 || any(this.stars, star => star.getLinks().length == 0)) {
this.stars = this.generateStars(starcount);
@ -27,7 +48,7 @@ module TS.SpaceTac {
this.generateWarpLocations();
this.stars.forEach((star: Star) => {
star.generate();
star.generate(this.random);
});
this.setEncounterLevels();

View file

@ -30,13 +30,13 @@ module TS.SpaceTac.Specs {
let fleet_size = fleet.ships.length;
checkPart(story, 0, "^Travel to Terranax galaxy$");
(<MissionPartDialog>story.current_part).skip();
(<MissionPartConversation>story.current_part).skip();
checkPart(story, 1, "^Find your contact in .*$");
goTo(fleet, (<MissionPartGoTo>story.current_part).destination);
checkPart(story, 2, "^Speak with your contact");
(<MissionPartDialog>story.current_part).skip();
(<MissionPartConversation>story.current_part).skip();
checkPart(story, 3, "^Go with .* in .* system$");
expect(fleet.ships.length).toBe(fleet_size + 1);

View file

@ -17,27 +17,27 @@ module TS.SpaceTac {
let start_location = nn(fleet.location);
// Arrival
let dialog = this.addPart(new MissionPartDialog(this, [], "Travel to Terranax galaxy"));
dialog.addPiece(null, "Wow ! From what my sensors tell me, there is not much activity around here.");
dialog.addPiece(null, "I remember the last time I came in this galaxy, you needed to be aware of collisions at all time, so crowded it was.");
dialog.addPiece(null, "Well...I did not pick a signal from our contact yet. We should be looking for her in this system.");
let conversation = this.addPart(new MissionPartConversation(this, [], "Travel to Terranax galaxy"));
conversation.addPiece(null, "Wow ! From what my sensors tell me, there is not much activity around here.");
conversation.addPiece(null, "I remember the last time I came in this galaxy, you needed to be aware of collisions at all time, so crowded it was.");
conversation.addPiece(null, "Well...I did not pick a signal from our contact yet. We should be looking for her in this system.");
// Get in touch with our contact
let contact_location = randomLocation(random, [start_location.star], [start_location]);
let contact_character = new Ship(null, "Osten-37", ShipModel.getRandomModel(1, random));
contact_character.fleet.setLocation(contact_location, true);
this.addPart(new MissionPartGoTo(this, contact_location, `Find your contact in ${contact_location.star.name}`));
dialog = this.addPart(new MissionPartDialog(this, [contact_character], "Speak with your contact"));
dialog.addPiece(contact_character, "Finally, you came!");
dialog.addPiece(contact_character, "Sorry for not broadcasting my position. As you may have encountered, this star system is not safe anymore.");
dialog.addPiece(null, "Nothing we could not handle, we just hope the other teams have not run across more trouble.");
dialog.addPiece(contact_character, "I do not even know if the other contacts made it to their rendezvous point. Jumping between systems has become quite a hassle around here.");
dialog.addPiece(null, "And we still do not know why those rogue fleets are trying to lockdown the whole galaxy? Did you have some interaction with them?");
dialog.addPiece(contact_character, "Well, they tend to shoot you on sight if you go near a location they defend. Do not know if that qualifies as interaction though...");
dialog.addPiece(null, "So where do we go from here? In your last message, you told us of a resistance group growing.");
dialog.addPiece(contact_character, "Yes, some merchants and miners have rallied behind a retired TSF general, but I lost contact with them weeks ago.");
dialog.addPiece(contact_character, "We may go to their last known location, but first I want you to see something in a nearby system.");
dialog.addPiece(null, "Ok, let's go...");
conversation = this.addPart(new MissionPartConversation(this, [contact_character], "Speak with your contact"));
conversation.addPiece(contact_character, "Finally, you came!");
conversation.addPiece(contact_character, "Sorry for not broadcasting my position. As you may have encountered, this star system is not safe anymore.");
conversation.addPiece(null, "Nothing we could not handle, we just hope the other teams have not run across more trouble.");
conversation.addPiece(contact_character, "I do not even know if the other contacts made it to their rendezvous point. Jumping between systems has become quite a hassle around here.");
conversation.addPiece(null, "And we still do not know why those rogue fleets are trying to lockdown the whole galaxy? Did you have some interaction with them?");
conversation.addPiece(contact_character, "Well, they tend to shoot you on sight if you go near a location they defend. Do not know if that qualifies as interaction though...");
conversation.addPiece(null, "So where do we go from here? In your last message, you told us of a resistance group growing.");
conversation.addPiece(contact_character, "Yes, some merchants and miners have rallied behind a retired TSF general, but I lost contact with them weeks ago.");
conversation.addPiece(contact_character, "We may go to their last known location, but first I want you to see something in a nearby system.");
conversation.addPiece(null, "Ok, let's go...");
// Go take a look at the graveyard
let nearby_systems = nna(start_location.star.getLinks().map(link => link.getPeer(contact_location.star)));

View file

@ -21,13 +21,17 @@ module TS.SpaceTac {
// Indicator that the mission is completed
completed: boolean
constructor(universe: Universe, fleet: Fleet, main = false) {
// Title of this mission (should be kept short)
title: string
constructor(universe: Universe, fleet = new Fleet(), main = false) {
this.universe = universe;
this.fleet = fleet;
this.main = main;
this.parts = [];
this.completed = false;
this.current_part = new MissionPart(this, "Empty mission");
this.title = main ? "Main story" : "Secondary mission";
}
/**

View file

@ -0,0 +1,24 @@
module TS.SpaceTac.Specs {
describe("MissionGenerator", () => {
it("generates escort missions", () => {
let universe = new Universe();
let star1 = universe.addStar(1);
let loc1 = star1.locations[0];
let star2 = universe.addStar(2);
let loc2 = star2.locations[0];
let star3 = universe.addStar(3);
let loc3 = star3.locations[0];
universe.addLink(star1, star2);
universe.addLink(star2, star3);
let generator = new MissionGenerator(universe, 3, loc2);
let mission = generator.generateEscort();
expect(mission.title).toBe("Escort a ship to a level 3 system");
expect(mission.parts.length).toBe(1);
expect(mission.parts[0] instanceof MissionPartEscort).toBe(true);
let escort = <MissionPartEscort>mission.parts[0];
expect(escort.destination).toBe(loc3);
});
});
}

View file

@ -0,0 +1,45 @@
module TS.SpaceTac {
/**
* Random generator of secondary missions that can be taken from
*/
export class MissionGenerator {
universe: Universe
level: number
around: StarLocation
random: RandomGenerator
constructor(universe: Universe, level: number, around: StarLocation, random = RandomGenerator.global) {
this.universe = universe;
this.level = level;
this.around = around;
this.random = random;
}
/**
* Generate a single mission
*/
generate(): Mission {
let generators = [
bound(this, "generateEscort")
];
let generator = this.random.choice(generators);
let result = generator();
// TODO Add reward
return result;
}
/**
* Generate an escort mission
*/
generateEscort(): Mission {
let mission = new Mission(this.universe);
let ship = new Ship();
let dest_star = minBy(this.around.star.getNeighbors(), star => Math.abs(star.level - this.level));
let destination = this.random.choice(dest_star.locations);
mission.addPart(new MissionPartEscort(mission, destination, ship));
mission.title = `Escort a ship to a level ${dest_star.level} system`;
return mission;
}
}
}

View file

@ -1,11 +1,11 @@
module TS.SpaceTac.Specs {
describe("MissionPartDialog", () => {
it("advances through dialog", function () {
describe("MissionPartConversation", () => {
it("advances through conversation", function () {
let universe = new Universe();
let fleet = new Fleet();
let ship1 = new Ship(null, "Tim");
let ship2 = new Ship(null, "Ben");
let part = new MissionPartDialog(new Mission(universe, fleet), [ship1, ship2], "Talk to Tim");
let part = new MissionPartConversation(new Mission(universe, fleet), [ship1, ship2], "Talk to Tim");
expect(part.title).toEqual("Talk to Tim");
expect(part.checkCompleted()).toBe(true, "No dialog piece");
@ -36,7 +36,7 @@ module TS.SpaceTac.Specs {
let universe = new Universe();
let fleet = new Fleet();
let ship = new Ship(null, "Tim");
let part = new MissionPartDialog(new Mission(universe, fleet), [ship]);
let part = new MissionPartConversation(new Mission(universe, fleet), [ship]);
part.addPiece(null, "Hello !");
part.addPiece(ship, "Hiya !");

View file

@ -2,9 +2,9 @@
module TS.SpaceTac {
/**
* A single dialog piece
* A single conversation piece
*/
interface DialogPiece {
interface ConversationPiece {
// Interlocutor (null for the player's fleet)
interlocutor: Ship | null
@ -13,14 +13,14 @@ module TS.SpaceTac {
}
/**
* A mission part that triggers a dialog
* A mission part that triggers a conversation
*/
export class MissionPartDialog extends MissionPart {
export class MissionPartConversation extends MissionPart {
// Other ships with which the dialog will take place
interlocutors: Ship[]
// Pieces of dialog
pieces: DialogPiece[] = []
pieces: ConversationPiece[] = []
// Current piece
current_piece = 0
@ -70,7 +70,7 @@ module TS.SpaceTac {
/**
* Get the current piece of dialog
*/
getCurrent(): DialogPiece {
getCurrent(): ConversationPiece {
if (this.checkCompleted()) {
return {
interlocutor: null,
@ -88,7 +88,7 @@ module TS.SpaceTac {
/**
* Get the interlocutor from the player fleet that will say the piece
*/
private getFleetInterlocutor(piece: DialogPiece): Ship | null {
private getFleetInterlocutor(piece: ConversationPiece): Ship | null {
if (this.fleet.ships.length > 0) {
// TODO Choose a ship by its personality traits
return this.fleet.ships[0];

View file

@ -18,6 +18,7 @@ module TS.SpaceTac.UI {
this.loadImage("common/arrow.png");
this.loadImage("common/button-ok.png");
this.loadImage("common/button-cancel.png");
this.loadImage("common/dialog.png");
this.loadSheet("common/dialog-close.png", 92, 82);
this.loadImage("menu/title.png");
this.loadImage("menu/button.png");
@ -70,6 +71,7 @@ module TS.SpaceTac.UI {
this.loadImage("map/location-warp.png");
this.loadSheet("map/status.png", 32);
this.loadSheet("map/missions.png", 70);
this.loadSheet("map/mission-action.png", 192, 56);
this.loadImage("character/sheet.png");
this.loadImage("character/close.png");
this.loadImage("character/ship.png");

View file

@ -231,8 +231,8 @@ module TS.SpaceTac.UI {
/**
* Add a static image, positioning its center.
*/
addImage(x: number, y: number, key: string, scale = 1): void {
let image = new Phaser.Image(this.container.game, x, y, key);
addImage(x: number, y: number, key: string, frame = 0, scale = 1): void {
let image = new Phaser.Image(this.container.game, x, y, key, frame);
image.anchor.set(0.5, 0.5);
image.scale.set(scale);
this.addInternalChild(image);

View file

@ -7,7 +7,7 @@ module TS.SpaceTac.UI {
* When a modal dialog opens, an overlay is displayed behind it to prevent clicking through it
*/
export class UIDialog extends UIComponent {
constructor(parent: BaseView, width: number, height: number, background: string) {
constructor(parent: BaseView, width = 1495, height = 1080, background = "common-dialog") {
super(parent, width, height, background);
if (parent.dialogs_layer.children.length == 0) {
@ -23,6 +23,7 @@ module TS.SpaceTac.UI {
*/
addOverlay(layer: Phaser.Group): void {
let overlay = layer.game.add.button(0, 0, "common-transparent", () => null);
overlay.input.useHandCursor = false;
overlay.scale.set(this.view.getWidth() / overlay.width, this.view.getHeight() / overlay.height);
layer.add(overlay);
}
@ -30,7 +31,7 @@ module TS.SpaceTac.UI {
/**
* Add a close button
*/
addCloseButton(key: string, x: number, y: number, frame = 0, frame_hover = 1): void {
addCloseButton(key = "common-dialog-close", x = 1325, y = 131, frame = 0, frame_hover = 1): void {
this.addButton(x, y, () => this.close(), key, frame, frame_hover, "Close this dialog");
}

View file

@ -8,7 +8,7 @@ module TS.SpaceTac.UI {
private missions: ActiveMissions
constructor(parent: BaseView, missions: ActiveMissions) {
super(parent, 520, 210);
super(parent, 520, 240);
this.missions = missions;
this.update();
@ -21,10 +21,11 @@ module TS.SpaceTac.UI {
this.clearContent();
let active = this.missions.getCurrent();
let offset = 245 - active.length * 70;
let spacing = 80;
let offset = 245 - active.length * spacing;
active.forEach((mission, idx) => {
this.addImage(35, offset + 70 * idx, "map-missions");
this.addText(90, offset + 70 * idx, mission.current_part.title, "#d2e1f3", 22, false, false, 430, true);
this.addImage(35, offset + spacing * idx, "map-missions", mission.main ? 0 : 1);
this.addText(90, offset + spacing * idx, mission.current_part.title, "#d2e1f3", 20, false, false, 430, true);
});
}
}

View file

@ -3,7 +3,7 @@ module TS.SpaceTac.UI {
* Display of an active conversation
*/
export class ConversationDisplay extends UIComponent {
dialog: MissionPartDialog | null = null
dialog: MissionPartConversation | null = null
player: Player
on_end: Function | null = null
@ -21,7 +21,7 @@ module TS.SpaceTac.UI {
*/
updateFromMissions(missions: ActiveMissions, on_end: Function | null = null) {
let parts = missions.getCurrent().map(mission => mission.current_part);
this.dialog = <MissionPartDialog | null>first(parts, part => part instanceof MissionPartDialog);
this.dialog = <MissionPartConversation | null>first(parts, part => part instanceof MissionPartConversation);
if (this.dialog) {
this.on_end = on_end;

View file

@ -34,7 +34,9 @@ module TS.SpaceTac.UI {
if (location) {
let actions: [string, Function][] = [];
if (location.shop) {
let shop = location.shop;
actions.push(["Go to dockyard", () => view.openShop()]);
actions.push(["Show jobs", () => new MissionsDialog(view, shop, view.player)]);
}
switch (location.type) {

View file

@ -0,0 +1,69 @@
module TS.SpaceTac.UI {
/**
* Dialog to show available missions
*/
export class MissionsDialog extends UIDialog {
shop: Shop
player: Player
location: StarLocation
constructor(view: BaseView, shop: Shop, player: Player) {
super(view);
this.shop = shop;
this.player = player;
this.location = player.fleet.location || new StarLocation();
this.refresh();
}
/**
* Refresh the dialog content
*/
refresh() {
this.clearContent();
this.addCloseButton();
let offset = 160;
let active = this.player.missions.getCurrent().filter(mission => !mission.main);
if (active.length) {
this.addText(this.width / 2, offset, "Active jobs", "#b8d2f1", 36);
offset += 110;
active.forEach(mission => {
this.addMission(offset, mission.title, "Reward: ???", 0, () => null);
offset += 110;
});
}
let proposed = this.shop.getMissions(this.location);
if (proposed.length) {
this.addText(this.width / 2, offset, "Proposed jobs", "#b8d2f1", 36);
offset += 110;
proposed.forEach(mission => {
this.addMission(offset, mission.title, "Reward: ???", 2, () => {
this.shop.acceptMission(mission, this.player);
this.refresh();
});
offset += 110;
});
}
}
/**
* Add a mission text
*/
addMission(yoffset: number, title: string, subtitle: string, button_frame: number, button_callback: Function) {
this.addImage(320, yoffset, "map-missions", 1);
if (title) {
this.addText(380, yoffset - 15, title, "#d2e1f3", 22, false, false, 620, true);
}
if (subtitle) {
this.addText(380, yoffset + 22, subtitle, "#d2e1f3", 20, false, false, 620, true);
}
this.addButton(1120, yoffset, button_callback, "map-mission-action", button_frame, button_frame + 1);
}
}
}