Files
2018-02-19 17:13:38 +03:00

5017 lines
177 KiB
Diff

diff -Nuar "a/data/levels/Desert Storm.trk" "b/data/levels/Desert Storm.trk"
--- "a/data/levels/Desert Storm.trk" 2017-12-30 16:09:21.000000000 +0300
+++ "b/data/levels/Desert Storm.trk" 2018-02-11 08:22:08.000000000 +0300
@@ -1,993 +1,993 @@
-<track cols="22" rows="22" index="13" version="1.13.0" name="Desert Storm">
- <t i="0" j="0" t="sand" o="0"/>
- <t i="0" j="1" t="sand" o="0"/>
- <t i="0" j="2" t="sand" o="0"/>
- <t i="0" j="3" t="sand" o="0"/>
- <t i="0" j="4" t="sand" o="0"/>
- <t i="0" j="5" t="sand" o="0"/>
- <t i="0" j="6" t="sand" o="0"/>
- <t i="0" j="7" t="sand" o="0"/>
- <t i="0" j="8" t="sand" o="0"/>
- <t i="0" j="9" t="sand" o="0"/>
- <t i="0" j="10" t="sand" o="0"/>
- <t i="0" j="11" t="sand" o="0"/>
- <t i="0" j="12" t="sand" o="0"/>
- <t i="0" j="13" t="sand" o="0"/>
- <t i="0" j="14" t="sand" o="0"/>
- <t i="0" j="15" t="sand" o="0"/>
- <t i="0" j="16" t="sand" o="0"/>
- <t i="0" j="17" t="sand" o="0"/>
- <t i="0" j="18" t="sand" o="0"/>
- <t i="0" j="19" t="sand" o="0"/>
- <t i="0" j="20" t="sand" o="0"/>
- <t i="0" j="21" t="sand" o="0"/>
- <t i="1" j="0" t="sand" o="0"/>
- <t i="1" j="1" t="sand" o="0"/>
- <t i="1" j="2" t="sand" o="0"/>
- <t i="1" j="3" t="sand" o="0"/>
- <t i="1" j="4" t="sand" o="0"/>
- <t i="1" j="5" t="sand" o="0"/>
- <t i="1" j="6" t="sand" o="0"/>
- <t i="1" j="7" t="sand" o="0"/>
- <t i="1" j="8" t="sand" o="0"/>
- <t i="1" j="9" t="sand" o="0"/>
- <t i="1" j="10" t="sand" o="0"/>
- <t i="1" j="11" t="sand" o="0"/>
- <t i="1" j="12" t="sandGrassCorner2" o="180"/>
- <t i="1" j="13" t="sandGrassStraight" o="90"/>
- <t i="1" j="14" t="sandGrassStraight" o="90"/>
- <t i="1" j="15" t="sandGrassStraight" o="90"/>
- <t i="1" j="16" t="sandGrassCorner2" o="90"/>
- <t i="1" j="17" t="sand" o="0"/>
- <t i="1" j="18" t="sand" o="0"/>
- <t i="1" j="19" t="sand" o="0"/>
- <t i="1" j="20" t="sand" o="0"/>
- <t i="1" j="21" t="sand" o="0"/>
- <t i="2" j="0" t="sand" o="0"/>
- <t i="2" j="1" t="sand" o="0"/>
- <t i="2" j="2" t="sand" o="0"/>
- <t i="2" j="3" t="sand" o="0"/>
- <t i="2" j="4" t="sand" o="0"/>
- <t i="2" j="5" t="sand" o="0"/>
- <t i="2" j="6" t="sand" o="0"/>
- <t i="2" j="7" t="sand" o="0"/>
- <t i="2" j="8" t="sand" o="0"/>
- <t i="2" j="9" t="sand" o="0"/>
- <t i="2" j="10" t="sand" o="0"/>
- <t i="2" j="11" t="sand" o="0"/>
- <t i="2" j="12" t="sandGrassStraight" o="180"/>
- <t i="2" j="13" t="corner90" o="0"/>
- <t i="2" j="14" t="straight" o="0"/>
- <t i="2" j="15" t="corner90" o="270"/>
- <t i="2" j="16" t="sandGrassStraight" o="0"/>
- <t i="2" j="17" t="sand" o="0"/>
- <t i="2" j="18" t="sand" o="0"/>
- <t i="2" j="19" t="sand" o="0"/>
- <t i="2" j="20" t="sand" o="0"/>
- <t i="2" j="21" t="sand" o="0"/>
- <t i="3" j="0" t="sand" o="0"/>
- <t i="3" j="1" t="sand" o="0"/>
- <t i="3" j="2" t="sand" o="0"/>
- <t i="3" j="3" t="sand" o="0"/>
- <t i="3" j="4" t="sandGrassCorner2" o="180"/>
- <t i="3" j="5" t="sandGrassStraight" o="90"/>
- <t i="3" j="6" t="sandGrassStraight" o="90"/>
- <t i="3" j="7" t="sandGrassStraight" o="90"/>
- <t i="3" j="8" t="sandGrassStraight" o="90"/>
- <t i="3" j="9" t="sandGrassStraight" o="90"/>
- <t i="3" j="10" t="sandGrassStraight" o="90"/>
- <t i="3" j="11" t="sandGrassStraight" o="90"/>
- <t i="3" j="12" t="sandGrassCorner" o="180"/>
- <t i="3" j="13" t="straight" o="90"/>
- <t i="3" j="14" t="grass" o="0"/>
- <t i="3" j="15" t="straight" o="90"/>
- <t i="3" j="16" t="sandGrassCorner" o="90"/>
- <t i="3" j="17" t="sandGrassStraight" o="90"/>
- <t i="3" j="18" t="sandGrassCorner2" o="90"/>
- <t i="3" j="19" t="sand" o="0"/>
- <t i="3" j="20" t="sand" o="0"/>
- <t i="3" j="21" t="sand" o="0"/>
- <t i="4" j="0" t="sand" o="0"/>
- <t i="4" j="1" t="sand" o="0"/>
- <t i="4" j="2" t="sand" o="0"/>
- <t i="4" j="3" t="sand" o="0"/>
- <t i="4" j="4" t="sandGrassStraight" o="180"/>
- <t i="4" j="5" t="corner90" o="0"/>
- <t i="4" j="6" c="1" t="straight" o="0"/>
- <t i="4" j="7" t="finish" o="0"/>
- <t i="4" j="8" t="straight" o="0"/>
- <t i="4" j="9" t="straight" o="0"/>
- <t i="4" j="10" t="straight" o="0"/>
- <t i="4" j="11" t="straight" o="0"/>
- <t i="4" j="12" t="straight" o="0"/>
- <t i="4" j="13" t="corner90" o="180"/>
- <t i="4" j="14" t="grass" o="0"/>
- <t i="4" j="15" t="corner90" o="90"/>
- <t i="4" j="16" t="straight" o="0"/>
- <t i="4" j="17" t="corner90" o="-90"/>
- <t i="4" j="18" t="sandGrassStraight" o="0"/>
- <t i="4" j="19" t="sand" o="0"/>
- <t i="4" j="20" t="sand" o="0"/>
- <t i="4" j="21" t="sand" o="0"/>
- <t i="5" j="0" t="sand" o="0"/>
- <t i="5" j="1" t="sand" o="0"/>
- <t i="5" j="2" t="sand" o="0"/>
- <t i="5" j="3" t="sand" o="0"/>
- <t i="5" j="4" t="sandGrassStraight" o="180"/>
- <t i="5" j="5" t="straight" o="90"/>
- <t i="5" j="6" t="sandGrassCorner" o="0"/>
- <t i="5" j="7" t="sandGrassStraight" o="270"/>
- <t i="5" j="8" t="sandGrassStraight" o="-90"/>
- <t i="5" j="9" t="sandGrassStraight" o="-90"/>
- <t i="5" j="10" t="sandGrassStraight" o="270"/>
- <t i="5" j="11" t="sandGrassStraight" o="-90"/>
- <t i="5" j="12" t="sandGrassStraight" o="-90"/>
- <t i="5" j="13" t="sandGrassStraight" o="270"/>
- <t i="5" j="14" t="sandGrassStraight" o="270"/>
- <t i="5" j="15" t="sandGrassStraight" o="270"/>
- <t i="5" j="16" t="sandGrassCorner" o="270"/>
- <t i="5" j="17" t="straight" o="90"/>
- <t i="5" j="18" t="sandGrassCorner" o="90"/>
- <t i="5" j="19" t="sandGrassStraight" o="90"/>
- <t i="5" j="20" t="sandGrassCorner2" o="90"/>
- <t i="5" j="21" t="sand" o="0"/>
- <t i="6" j="0" t="sand" o="0"/>
- <t i="6" j="1" t="sandGrassCorner2" o="180"/>
- <t i="6" j="2" t="sandGrassStraight" o="90"/>
- <t i="6" j="3" t="sandGrassStraight" o="90"/>
- <t i="6" j="4" t="sandGrassCorner" o="180"/>
- <t i="6" j="5" t="straight" o="90"/>
- <t i="6" j="6" t="sandGrassStraight" o="0"/>
- <t i="6" j="7" t="sandGrassCorner2" o="180"/>
- <t i="6" j="8" t="sandGrassStraight" o="90"/>
- <t i="6" j="9" t="sandGrassStraight" o="90"/>
- <t i="6" j="10" t="sandGrassStraight" o="90"/>
- <t i="6" j="11" t="sandGrassStraight" o="90"/>
- <t i="6" j="12" t="sandGrassCorner2" o="90"/>
- <t i="6" j="13" t="sand" o="0"/>
- <t i="6" j="14" t="sand" o="0"/>
- <t i="6" j="15" t="sand" o="0"/>
- <t i="6" j="16" t="sandGrassStraight" o="180"/>
- <t i="6" j="17" t="corner90" o="90"/>
- <t i="6" j="18" t="straight" o="0"/>
- <t i="6" j="19" t="corner90" o="270"/>
- <t i="6" j="20" t="sandGrassStraight" o="0"/>
- <t i="6" j="21" t="sand" o="0"/>
- <t i="7" j="0" t="sand" o="0"/>
- <t i="7" j="1" t="sandGrassStraight" o="180"/>
- <t i="7" j="2" t="corner90" o="0"/>
- <t i="7" j="3" t="straight" o="0"/>
- <t i="7" j="4" t="straight" o="0"/>
- <t i="7" j="5" t="corner90" o="180"/>
- <t i="7" j="6" t="sandGrassStraight" o="0"/>
- <t i="7" j="7" t="sandGrassStraight" o="180"/>
- <t i="7" j="8" t="corner90" o="0"/>
- <t i="7" j="9" t="straight" o="0"/>
- <t i="7" j="10" t="straight" o="0"/>
- <t i="7" j="11" t="corner90" o="270"/>
- <t i="7" j="12" t="sandGrassStraight" o="0"/>
- <t i="7" j="13" t="sand" o="0"/>
- <t i="7" j="14" t="sand" o="0"/>
- <t i="7" j="15" t="sand" o="0"/>
- <t i="7" j="16" t="sandGrassCorner2" o="270"/>
- <t i="7" j="17" t="sandGrassStraight" o="270"/>
- <t i="7" j="18" t="sandGrassCorner" o="270"/>
- <t i="7" j="19" t="straight" o="90"/>
- <t i="7" j="20" t="sandGrassStraight" o="0"/>
- <t i="7" j="21" t="sand" o="0"/>
- <t i="8" j="0" t="sand" o="0"/>
- <t i="8" j="1" t="sandGrassStraight" o="180"/>
- <t i="8" j="2" t="straight" o="90"/>
- <t i="8" j="3" t="sandGrassCorner" o="0"/>
- <t i="8" j="4" t="sandGrassStraight" o="-90"/>
- <t i="8" j="5" t="sandGrassStraight" o="-90"/>
- <t i="8" j="6" t="sandGrassCorner2" o="0"/>
- <t i="8" j="7" t="sandGrassStraight" o="180"/>
- <t i="8" j="8" t="straight" o="90"/>
- <t i="8" j="9" t="sandGrassCorner" o="360"/>
- <t i="8" j="10" t="sandGrassCorner" o="270"/>
- <t i="8" j="11" t="straight" o="90"/>
- <t i="8" j="12" t="sandGrassStraight" o="0"/>
- <t i="8" j="13" t="sand" o="0"/>
- <t i="8" j="14" t="sandGrassCorner2" o="180"/>
- <t i="8" j="15" t="sandGrassStraight" o="90"/>
- <t i="8" j="16" t="sandGrassStraight" o="90"/>
- <t i="8" j="17" t="sandGrassStraight" o="90"/>
- <t i="8" j="18" t="sandGrassCorner" o="180"/>
- <t i="8" j="19" t="straight" o="90"/>
- <t i="8" j="20" t="sandGrassStraight" o="0"/>
- <t i="8" j="21" t="sand" o="0"/>
- <t i="9" j="0" t="sand" o="0"/>
- <t i="9" j="1" t="sandGrassStraight" o="180"/>
- <t i="9" j="2" t="straight" o="90"/>
- <t i="9" j="3" t="sandGrassCorner" o="90"/>
- <t i="9" j="4" t="sandGrassStraight" o="90"/>
- <t i="9" j="5" t="sandGrassStraight" o="90"/>
- <t i="9" j="6" t="sandGrassStraight" o="90"/>
- <t i="9" j="7" t="sandGrassCorner" o="180"/>
- <t i="9" j="8" t="straight" o="90"/>
- <t i="9" j="9" t="sandGrassStraight" o="0"/>
- <t i="9" j="10" t="sandGrassStraight" o="180"/>
- <t i="9" j="11" t="straight" o="90"/>
- <t i="9" j="12" t="sandGrassStraight" o="0"/>
- <t i="9" j="13" t="sand" o="0"/>
- <t i="9" j="14" t="sandGrassStraight" o="180"/>
- <t i="9" j="15" t="corner90" o="0"/>
- <t i="9" j="16" t="straight" o="0"/>
- <t i="9" j="17" t="straight" o="0"/>
- <t i="9" j="18" c="2" t="straight" o="0"/>
- <t i="9" j="19" t="corner90" o="-180"/>
- <t i="9" j="20" t="sandGrassStraight" o="0"/>
- <t i="9" j="21" t="sand" o="0"/>
- <t i="10" j="0" t="sand" o="0"/>
- <t i="10" j="1" t="sandGrassStraight" o="180"/>
- <t i="10" j="2" t="corner90" o="90"/>
- <t i="10" j="3" t="straight" o="0"/>
- <t i="10" j="4" t="straight" o="0"/>
- <t i="10" j="5" t="straight" o="0"/>
- <t i="10" j="6" c="2" t="straight" o="0"/>
- <t i="10" j="7" c="2" t="straight" o="0"/>
- <t i="10" j="8" t="corner90" o="180"/>
- <t i="10" j="9" t="sandGrassStraight" o="0"/>
- <t i="10" j="10" t="sandGrassStraight" o="180"/>
- <t i="10" j="11" t="straight" o="90"/>
- <t i="10" j="12" t="sandGrassStraight" o="0"/>
- <t i="10" j="13" t="sand" o="0"/>
- <t i="10" j="14" t="sandGrassStraight" o="180"/>
- <t i="10" j="15" t="straight" o="90"/>
- <t i="10" j="16" t="sandGrassCorner" o="0"/>
- <t i="10" j="17" t="sandGrassStraight" o="-90"/>
- <t i="10" j="18" t="sandGrassStraight" o="-90"/>
- <t i="10" j="19" t="sandGrassStraight" o="-90"/>
- <t i="10" j="20" t="sandGrassCorner2" o="0"/>
- <t i="10" j="21" t="sand" o="0"/>
- <t i="11" j="0" t="sand" o="0"/>
- <t i="11" j="1" t="sandGrassCorner2" o="270"/>
- <t i="11" j="2" t="sandGrassStraight" o="-90"/>
- <t i="11" j="3" t="sandGrassStraight" o="-90"/>
- <t i="11" j="4" t="sandGrassStraight" o="-90"/>
- <t i="11" j="5" t="sandGrassStraight" o="-90"/>
- <t i="11" j="6" t="sandGrassStraight" o="-90"/>
- <t i="11" j="7" t="sandGrassStraight" o="-90"/>
- <t i="11" j="8" t="sandGrassStraight" o="-90"/>
- <t i="11" j="9" t="sandGrassCorner2" o="0"/>
- <t i="11" j="10" t="sandGrassStraight" o="180"/>
- <t i="11" j="11" t="straight" o="270"/>
- <t i="11" j="12" t="sandGrassStraight" o="0"/>
- <t i="11" j="13" t="sand" o="0"/>
- <t i="11" j="14" t="sandGrassStraight" o="180"/>
- <t i="11" j="15" t="straight" o="90"/>
- <t i="11" j="16" t="sandGrassCorner" o="90"/>
- <t i="11" j="17" t="sandGrassStraight" o="90"/>
- <t i="11" j="18" t="sandGrassStraight" o="90"/>
- <t i="11" j="19" t="sandGrassCorner2" o="90"/>
- <t i="11" j="20" t="sand" o="0"/>
- <t i="11" j="21" t="sand" o="0"/>
- <t i="12" j="0" t="sand" o="0"/>
- <t i="12" j="1" t="sand" o="0"/>
- <t i="12" j="2" t="sand" o="0"/>
- <t i="12" j="3" t="sand" o="0"/>
- <t i="12" j="4" t="sandGrassCorner2" o="180"/>
- <t i="12" j="5" t="sandGrassStraight" o="90"/>
- <t i="12" j="6" t="sandGrassStraight" o="90"/>
- <t i="12" j="7" t="sandGrassStraight" o="90"/>
- <t i="12" j="8" t="sandGrassStraight" o="90"/>
- <t i="12" j="9" t="sandGrassStraight" o="90"/>
- <t i="12" j="10" t="sandGrassCorner" o="180"/>
- <t i="12" j="11" c="2" t="straight" o="90"/>
- <t i="12" j="12" t="sandGrassStraight" o="0"/>
- <t i="12" j="13" t="sand" o="0"/>
- <t i="12" j="14" t="sandGrassStraight" o="180"/>
- <t i="12" j="15" t="corner90" o="90"/>
- <t i="12" j="16" t="straight" o="0"/>
- <t i="12" j="17" t="straight" o="180"/>
- <t i="12" j="18" t="corner90" o="270"/>
- <t i="12" j="19" t="sandGrassStraight" o="0"/>
- <t i="12" j="20" t="sand" o="0"/>
- <t i="12" j="21" t="sand" o="0"/>
- <t i="13" j="0" t="sand" o="0"/>
- <t i="13" j="1" t="sand" o="0"/>
- <t i="13" j="2" t="sand" o="0"/>
- <t i="13" j="3" t="sand" o="0"/>
- <t i="13" j="4" t="sandGrassStraight" o="-180"/>
- <t i="13" j="5" t="corner90" o="0"/>
- <t i="13" j="6" c="2" t="straight" o="0"/>
- <t i="13" j="7" t="straight" o="0"/>
- <t i="13" j="8" t="straight" o="0"/>
- <t i="13" j="9" t="straight" o="0"/>
- <t i="13" j="10" t="straight" o="0"/>
- <t i="13" j="11" t="corner90" o="-180"/>
- <t i="13" j="12" t="sandGrassStraight" o="0"/>
- <t i="13" j="13" t="sand" o="0"/>
- <t i="13" j="14" t="sandGrassStraight" o="180"/>
- <t i="13" j="15" t="grass" o="0"/>
- <t i="13" j="16" t="grass" o="0"/>
- <t i="13" j="17" t="grass" o="0"/>
- <t i="13" j="18" t="straight" o="90"/>
- <t i="13" j="19" t="sandGrassStraight" o="0"/>
- <t i="13" j="20" t="sand" o="0"/>
- <t i="13" j="21" t="sand" o="0"/>
- <t i="14" j="0" t="sand" o="0"/>
- <t i="14" j="1" t="sand" o="0"/>
- <t i="14" j="2" t="sand" o="0"/>
- <t i="14" j="3" t="sand" o="0"/>
- <t i="14" j="4" t="sandGrassStraight" o="180"/>
- <t i="14" j="5" t="straight" o="90"/>
- <t i="14" j="6" t="grass" o="0"/>
- <t i="14" j="7" t="grass" o="0"/>
- <t i="14" j="8" t="sandGrassCorner" o="0"/>
- <t i="14" j="9" t="sandGrassStraight" o="-90"/>
- <t i="14" j="10" t="sandGrassStraight" o="-90"/>
- <t i="14" j="11" t="sandGrassStraight" o="-90"/>
- <t i="14" j="12" t="sandGrassCorner2" o="0"/>
- <t i="14" j="13" t="sand" o="0"/>
- <t i="14" j="14" t="sandGrassStraight" o="180"/>
- <t i="14" j="15" t="corner90" o="0"/>
- <t i="14" j="16" t="straight" o="0"/>
- <t i="14" j="17" t="straight" o="0"/>
- <t i="14" j="18" t="corner90" o="180"/>
- <t i="14" j="19" t="sandGrassStraight" o="0"/>
- <t i="14" j="20" t="sand" o="0"/>
- <t i="14" j="21" t="sand" o="0"/>
- <t i="15" j="0" t="sand" o="0"/>
- <t i="15" j="1" t="sand" o="0"/>
- <t i="15" j="2" t="sand" o="0"/>
- <t i="15" j="3" t="sand" o="0"/>
- <t i="15" j="4" t="sandGrassStraight" o="180"/>
- <t i="15" j="5" t="corner90" o="90"/>
- <t i="15" j="6" t="straight" o="0"/>
- <t i="15" j="7" t="corner90" o="270"/>
- <t i="15" j="8" t="sandGrassStraight" o="0"/>
- <t i="15" j="9" t="sandGrassCorner2" o="180"/>
- <t i="15" j="10" t="sandGrassStraight" o="90"/>
- <t i="15" j="11" t="sandGrassStraight" o="90"/>
- <t i="15" j="12" t="sandGrassStraight" o="90"/>
- <t i="15" j="13" t="sandGrassStraight" o="90"/>
- <t i="15" j="14" t="sandGrassCorner" o="180"/>
- <t i="15" j="15" t="straight" o="90"/>
- <t i="15" j="16" t="sandGrassCorner" o="0"/>
- <t i="15" j="17" t="sandGrassStraight" o="-90"/>
- <t i="15" j="18" t="sandGrassStraight" o="-90"/>
- <t i="15" j="19" t="sandGrassCorner2" o="0"/>
- <t i="15" j="20" t="sand" o="0"/>
- <t i="15" j="21" t="sand" o="0"/>
- <t i="16" j="0" t="sand" o="0"/>
- <t i="16" j="1" t="sand" o="0"/>
- <t i="16" j="2" t="sand" o="0"/>
- <t i="16" j="3" t="sand" o="0"/>
- <t i="16" j="4" t="sandGrassStraight" o="180"/>
- <t i="16" j="5" t="grass" o="0"/>
- <t i="16" j="6" t="grass" o="0"/>
- <t i="16" j="7" t="straight" o="90"/>
- <t i="16" j="8" t="sandGrassStraight" o="0"/>
- <t i="16" j="9" t="sandGrassStraight" o="180"/>
- <t i="16" j="10" t="corner90" o="0"/>
- <t i="16" j="11" t="straight" o="0"/>
- <t i="16" j="12" t="straight" o="0"/>
- <t i="16" j="13" t="corner90" o="270"/>
- <t i="16" j="14" t="grass" o="0"/>
- <t i="16" j="15" t="straight" o="90"/>
- <t i="16" j="16" t="sandGrassStraight" o="0"/>
- <t i="16" j="17" t="sand" o="0"/>
- <t i="16" j="18" t="sand" o="0"/>
- <t i="16" j="19" t="sand" o="0"/>
- <t i="16" j="20" t="sand" o="0"/>
- <t i="16" j="21" t="sand" o="0"/>
- <t i="17" j="0" t="sand" o="0"/>
- <t i="17" j="1" t="sand" o="0"/>
- <t i="17" j="2" t="sand" o="0"/>
- <t i="17" j="3" t="sand" o="0"/>
- <t i="17" j="4" t="sandGrassStraight" o="180"/>
- <t i="17" j="5" t="corner90" o="0"/>
- <t i="17" j="6" t="straight" o="0"/>
- <t i="17" j="7" t="corner90" o="180"/>
- <t i="17" j="8" t="sandGrassStraight" o="0"/>
- <t i="17" j="9" t="sandGrassStraight" o="180"/>
- <t i="17" j="10" t="straight" o="90"/>
- <t i="17" j="11" t="sandGrassCorner" o="0"/>
- <t i="17" j="12" t="sandGrassCorner" o="270"/>
- <t i="17" j="13" t="straight" o="90"/>
- <t i="17" j="14" t="grass" o="0"/>
- <t i="17" j="15" t="straight" o="90"/>
- <t i="17" j="16" t="sandGrassStraight" o="0"/>
- <t i="17" j="17" t="sand" o="0"/>
- <t i="17" j="18" t="sand" o="0"/>
- <t i="17" j="19" t="sand" o="0"/>
- <t i="17" j="20" t="sand" o="0"/>
- <t i="17" j="21" t="sand" o="0"/>
- <t i="18" j="0" t="sand" o="0"/>
- <t i="18" j="1" t="sand" o="0"/>
- <t i="18" j="2" t="sand" o="0"/>
- <t i="18" j="3" t="sand" o="0"/>
- <t i="18" j="4" t="sandGrassStraight" o="180"/>
- <t i="18" j="5" t="straight" o="90"/>
- <t i="18" j="6" t="grass" o="0"/>
- <t i="18" j="7" t="grass" o="0"/>
- <t i="18" j="8" t="sandGrassCorner" o="90"/>
- <t i="18" j="9" t="sandGrassCorner" o="180"/>
- <t i="18" j="10" t="straight" o="90"/>
- <t i="18" j="11" t="sandGrassStraight" o="0"/>
- <t i="18" j="12" t="sandGrassStraight" o="180"/>
- <t i="18" j="13" t="corner90" o="90"/>
- <t i="18" j="14" t="straight" o="0"/>
- <t i="18" j="15" t="corner90" o="180"/>
- <t i="18" j="16" t="sandGrassStraight" o="0"/>
- <t i="18" j="17" t="sand" o="0"/>
- <t i="18" j="18" t="sand" o="0"/>
- <t i="18" j="19" t="sand" o="0"/>
- <t i="18" j="20" t="sand" o="0"/>
- <t i="18" j="21" t="sand" o="0"/>
- <t i="19" j="0" t="sand" o="0"/>
- <t i="19" j="1" t="sand" o="0"/>
- <t i="19" j="2" t="sand" o="0"/>
- <t i="19" j="3" t="sand" o="0"/>
- <t i="19" j="4" t="sandGrassStraight" o="180"/>
- <t i="19" j="5" t="corner90" o="90"/>
- <t i="19" j="6" t="straight" o="0"/>
- <t i="19" j="7" t="straight" o="0"/>
- <t i="19" j="8" t="straight" o="0"/>
- <t i="19" j="9" t="straight" o="0"/>
- <t i="19" j="10" t="corner90" o="180"/>
- <t i="19" j="11" t="sandGrassStraight" o="0"/>
- <t i="19" j="12" t="sandGrassCorner2" o="270"/>
- <t i="19" j="13" t="sandGrassStraight" o="270"/>
- <t i="19" j="14" t="sandGrassStraight" o="-90"/>
- <t i="19" j="15" t="sandGrassStraight" o="-90"/>
- <t i="19" j="16" t="sandGrassCorner2" o="0"/>
- <t i="19" j="17" t="sand" o="0"/>
- <t i="19" j="18" t="sand" o="0"/>
- <t i="19" j="19" t="sand" o="0"/>
- <t i="19" j="20" t="sand" o="0"/>
- <t i="19" j="21" t="sand" o="0"/>
- <t i="20" j="0" t="sand" o="0"/>
- <t i="20" j="1" t="sand" o="0"/>
- <t i="20" j="2" t="sand" o="0"/>
- <t i="20" j="3" t="sand" o="0"/>
- <t i="20" j="4" t="sandGrassCorner2" o="270"/>
- <t i="20" j="5" t="sandGrassStraight" o="270"/>
- <t i="20" j="6" t="sandGrassStraight" o="270"/>
- <t i="20" j="7" t="sandGrassStraight" o="-90"/>
- <t i="20" j="8" t="sandGrassStraight" o="-90"/>
- <t i="20" j="9" t="sandGrassStraight" o="-90"/>
- <t i="20" j="10" t="sandGrassStraight" o="-90"/>
- <t i="20" j="11" t="sandGrassCorner2" o="0"/>
- <t i="20" j="12" t="sand" o="0"/>
- <t i="20" j="13" t="sand" o="0"/>
- <t i="20" j="14" t="sand" o="0"/>
- <t i="20" j="15" t="sand" o="0"/>
- <t i="20" j="16" t="sand" o="0"/>
- <t i="20" j="17" t="sand" o="0"/>
- <t i="20" j="18" t="sand" o="0"/>
- <t i="20" j="19" t="sand" o="0"/>
- <t i="20" j="20" t="sand" o="0"/>
- <t i="20" j="21" t="sand" o="0"/>
- <t i="21" j="0" t="sand" o="0"/>
- <t i="21" j="1" t="sand" o="0"/>
- <t i="21" j="2" t="sand" o="0"/>
- <t i="21" j="3" t="sand" o="0"/>
- <t i="21" j="4" t="sand" o="0"/>
- <t i="21" j="5" t="sand" o="0"/>
- <t i="21" j="6" t="sand" o="0"/>
- <t i="21" j="7" t="sand" o="0"/>
- <t i="21" j="8" t="sand" o="0"/>
- <t i="21" j="9" t="sand" o="0"/>
- <t i="21" j="10" t="sand" o="0"/>
- <t i="21" j="11" t="sand" o="0"/>
- <t i="21" j="12" t="sand" o="90"/>
- <t i="21" j="13" t="sand" o="0"/>
- <t i="21" j="14" t="sand" o="0"/>
- <t i="21" j="15" t="sand" o="0"/>
- <t i="21" j="16" t="sand" o="0"/>
- <t i="21" j="17" t="sand" o="0"/>
- <t i="21" j="18" t="sand" o="0"/>
- <t i="21" j="19" t="sand" o="0"/>
- <t i="21" j="20" t="sand" o="0"/>
- <t i="21" j="21" t="sand" o="0"/>
- <o x="1081" c="free" o="90" r="pit" y="1659"/>
- <o x="791" c="free" o="0" r="sandAreaCurve" y="3606"/>
- <o x="791" c="free" o="270" r="sandAreaCurve" y="3814"/>
- <o x="3572" c="free" o="90" r="wallLong" y="4192"/>
- <o x="3573" c="free" o="90" r="wallLong" y="4450"/>
- <o x="3572" c="free" o="90" r="wall" y="4022"/>
- <o x="3585" c="free" o="110" r="wall" y="3946"/>
- <o x="3631" c="free" o="140" r="wall" y="3867"/>
- <o x="4159" c="free" o="180" r="grandstand" y="3648"/>
- <o x="4294" c="free" o="180" r="grandstand" y="3647"/>
- <o x="4430" c="free" o="180" r="grandstand" y="3645"/>
- <o x="4156" c="free" o="0" r="grandstand" y="3785"/>
- <o x="4297" c="free" o="0" r="grandstand" y="3779"/>
- <o x="4430" c="free" o="0" r="grandstand" y="3779"/>
- <o x="3836" c="free" o="0" r="dustRacing2DBanner" y="3789"/>
- <o x="4224" c="free" o="0" r="dustRacing2DBanner" y="1776"/>
- <o x="4113" c="free" o="90" r="dustRacing2DBanner" y="1624"/>
- <o x="4332" c="free" o="270" r="dustRacing2DBanner" y="1630"/>
- <o x="4107" c="free" o="90" r="wallLong" y="1362"/>
- <o x="4341" c="free" o="90" r="wallLong" y="1367"/>
- <o x="4625" c="free" o="90" r="dustRacing2DBanner" y="1663"/>
- <o x="4625" c="free" o="90" r="dustRacing2DBanner" y="1926"/>
- <o x="4712" c="free" o="180" r="grandstand" y="1597"/>
- <o x="4799" c="free" o="270" r="grandstand" y="1776"/>
- <o x="4799" c="free" o="-90" r="grandstand" y="1944"/>
- <o x="930" c="free" o="0" r="wallLong" y="3829"/>
- <o x="1188" c="free" o="0" r="wallLong" y="3829"/>
- <o x="927" c="free" o="0" r="wallLong" y="3596"/>
- <o x="1186" c="free" o="0" r="wallLong" y="3596"/>
- <o x="807" c="free" o="90" r="wall" y="3641"/>
- <o x="808" c="free" o="90" r="wall" y="3711"/>
- <o x="808" c="free" o="90" r="wall" y="3780"/>
- <o x="3451" c="free" o="0" r="bushArea" y="4123"/>
- <o x="4241" c="free" o="0" r="plant" y="1547"/>
- <o x="4818" c="free" o="0" r="plant" y="1603"/>
- <o x="3603" c="free" o="90" r="dustRacing2DBanner" y="1995"/>
- <o x="3603" c="free" o="90" r="dustRacing2DBanner" y="1726"/>
- <o x="3710" c="free" o="0" r="dustRacing2DBanner" y="1565"/>
- <o x="2968" c="free" o="270" r="right" y="2778"/>
- <o x="3295" c="free" o="0" r="right" y="1656"/>
- <o x="2105" c="free" o="0" r="right" y="2641"/>
- <o x="2123" c="free" o="270" r="left" y="1989"/>
- <o x="2847" c="free" o="0" r="left" y="1669"/>
- <o x="2078" c="free" o="0" r="right" y="958"/>
- <o x="2079" c="free" o="0" r="right" y="1021"/>
- <o x="3296" c="free" o="0" r="right" y="1723"/>
- <o x="4757" c="free" o="90" r="right" y="1243"/>
- <o x="4805" c="free" o="0" r="left" y="2191"/>
- <o x="4570" c="free" o="270" r="left" y="3290"/>
- <o x="4516" c="free" o="-90" r="left" y="3290"/>
- <o x="3870" c="free" o="0" r="left" y="4486"/>
- <o x="3873" c="free" o="0" r="left" y="4430"/>
- <o x="1336" c="free" o="0" r="brake" y="1848"/>
- <o x="968" c="free" o="0" r="brake" y="1849"/>
- <o x="1338" c="free" o="0" r="right" y="1897"/>
- <o x="973" c="free" o="0" r="right" y="1913"/>
- <o x="479" c="free" o="0" r="right" y="3702"/>
- <o x="1237" c="free" o="0" r="left" y="3801"/>
- <o x="1295" c="free" o="90" r="left" y="3500"/>
- <o x="1297" c="free" o="90" r="left" y="3382"/>
- <o x="3030" c="free" o="0" r="left" y="4373"/>
- <o x="3290" c="free" o="0" r="brake" y="1597"/>
- <o x="2729" c="free" o="180" r="dustRacing2DBanner" y="2339"/>
- <o x="2463" c="free" o="180" r="dustRacing2DBanner" y="2340"/>
- <o x="2193" c="free" o="180" r="dustRacing2DBanner" y="2338"/>
- <o x="2204" c="free" o="180" r="grandstand" y="2440"/>
- <o x="2366" c="free" o="180" r="grandstand" y="2440"/>
- <o x="2527" c="free" o="180" r="grandstand" y="2440"/>
- <o x="2680" c="free" o="180" r="grandstand" y="2439"/>
- <o x="3112" c="free" o="0" r="rock" y="1248"/>
- <o x="3076" c="free" o="0" r="rock" y="1435"/>
- <o x="3008" c="free" o="0" r="rock" y="1546"/>
- <o x="3138" c="free" o="0" r="rock" y="1245"/>
- <o x="2980" c="free" o="0" r="rock" y="1131"/>
- <o x="3152" c="free" o="0" r="rock" y="1080"/>
- <o x="3224" c="free" o="0" r="rock" y="1059"/>
- <o x="3300" c="free" o="0" r="rock" y="1014"/>
- <o x="3066" c="free" o="0" r="rock" y="883"/>
- <o x="3011" c="free" o="0" r="rock" y="1059"/>
- <o x="3211" c="free" o="0" r="rock" y="1135"/>
- <o x="3242" c="free" o="0" r="rock" y="1242"/>
- <o x="2976" c="free" o="0" r="rock" y="1328"/>
- <o x="2997" c="free" o="0" r="rock" y="1183"/>
- <o x="3121" c="free" o="0" r="rock" y="1345"/>
- <o x="3176" c="free" o="0" r="rock" y="1397"/>
- <o x="3352" c="free" o="0" r="rock" y="1018"/>
- <o x="3121" c="free" o="0" r="rock" y="887"/>
- <o x="3187" c="free" o="0" r="rock" y="728"/>
- <o x="3328" c="free" o="0" r="rock" y="752"/>
- <o x="2973" c="free" o="0" r="rock" y="680"/>
- <o x="2918" c="free" o="0" r="rock" y="442"/>
- <o x="2718" c="free" o="0" r="rock" y="369"/>
- <o x="2938" c="free" o="0" r="rock" y="421"/>
- <o x="2987" c="free" o="0" r="rock" y="573"/>
- <o x="3093" c="free" o="0" r="rock" y="593"/>
- <o x="3307" c="free" o="0" r="rock" y="593"/>
- <o x="3204" c="free" o="0" r="rock" y="883"/>
- <o x="2980" c="free" o="0" r="rock" y="849"/>
- <o x="3021" c="free" o="0" r="rock" y="966"/>
- <o x="3211" c="free" o="0" r="rock" y="969"/>
- <o x="2952" c="free" o="0" r="rock" y="1231"/>
- <o x="3100" c="free" o="0" r="rock" y="1124"/>
- <o x="3187" c="free" o="0" r="rock" y="1497"/>
- <o x="3921" c="free" o="0" r="rock" y="2400"/>
- <o x="4404" c="free" o="0" r="rock" y="2197"/>
- <o x="4511" c="free" o="0" r="rock" y="2338"/>
- <o x="4659" c="free" o="0" r="rock" y="2235"/>
- <o x="4652" c="free" o="0" r="rock" y="2366"/>
- <o x="4290" c="free" o="0" r="rock" y="2438"/>
- <o x="4035" c="free" o="0" r="rock" y="2218"/>
- <o x="3811" c="free" o="0" r="rock" y="2235"/>
- <o x="4014" c="free" o="0" r="rock" y="2335"/>
- <o x="3845" c="free" o="0" r="rock" y="2604"/>
- <o x="3869" c="free" o="0" r="rock" y="2724"/>
- <o x="3776" c="free" o="0" r="rock" y="2773"/>
- <o x="3949" c="free" o="0" r="rock" y="2924"/>
- <o x="3842" c="free" o="0" r="rock" y="3004"/>
- <o x="3883" c="free" o="0" r="rock" y="3131"/>
- <o x="2967" c="free" o="0" r="rock" y="1881"/>
- <o x="3138" c="free" o="0" r="rock" y="1887"/>
- <o x="3045" c="free" o="0" r="rock" y="2011"/>
- <o x="3073" c="free" o="0" r="rock" y="2156"/>
- <o x="2945" c="free" o="0" r="rock" y="1652"/>
- <o x="2338" c="free" o="0" r="rock" y="949"/>
- <o x="2242" c="free" o="0" r="rock" y="921"/>
- <o x="2476" c="free" o="0" r="rock" y="918"/>
- <o x="2428" c="free" o="0" r="rock" y="883"/>
- <o x="1418" c="free" o="0" r="rock" y="1004"/>
- <o x="1311" c="free" o="0" r="rock" y="1124"/>
- <o x="1611" c="free" o="0" r="rock" y="838"/>
- <o x="1093" c="free" o="0" r="wallLong" y="1030"/>
- <o x="1357" c="free" o="0" r="wallLong" y="1028"/>
- <o x="2156" c="free" o="90" r="wallLong" y="998"/>
- <o x="2158" c="free" o="90" r="wallLong" y="1276"/>
- <o x="2183" c="free" o="90" r="wallLong" y="3880"/>
- <o x="2184" c="free" o="90" r="wallLong" y="4417"/>
- <o x="2183" c="free" o="90" r="wallLong" y="4688"/>
- <o x="2996" c="free" o="90" r="wallLong" y="4702"/>
- <o x="4498" c="free" o="0" r="rock" y="2921"/>
- <o x="4692" c="free" o="0" r="rock" y="2925"/>
- <o x="4588" c="free" o="0" r="rock" y="2907"/>
- <o x="4772" c="free" o="0" r="rock" y="2945"/>
- <o x="4925" c="free" o="0" r="rock" y="3068"/>
- <o x="4587" c="free" o="0" r="rock" y="3130"/>
- <o x="4453" c="free" o="0" r="rock" y="2927"/>
- <o x="4486" c="free" o="0" r="rock" y="2978"/>
- <o x="4515" c="free" o="0" r="rock" y="3072"/>
- <o x="4596" c="free" o="0" r="rock" y="3017"/>
- <o x="4458" c="free" o="0" r="rock" y="3035"/>
- <o x="4439" c="free" o="0" r="rock" y="2956"/>
- <o x="4443" c="free" o="0" r="rock" y="3100"/>
- <o x="4462" c="free" o="0" r="rock" y="3160"/>
- <o x="4566" c="free" o="0" r="rock" y="2958"/>
- <o x="4529" c="free" o="0" r="rock" y="2982"/>
- <o x="4653" c="free" o="0" r="rock" y="2972"/>
- <o x="4690" c="free" o="0" r="rock" y="3027"/>
- <o x="4945" c="free" o="0" r="rock" y="2998"/>
- <o x="4798" c="free" o="0" r="rock" y="3031"/>
- <o x="1394" c="free" o="0" r="crate" y="4047"/>
- <o x="1570" c="free" o="0" r="crate" y="4156"/>
- <o x="1398" c="free" o="0" r="crate" y="4262"/>
- <o x="1474" c="free" o="0" r="crate" y="4276"/>
- <o x="1590" c="free" o="0" r="crate" y="4294"/>
- <o x="1702" c="free" o="0" r="crate" y="4292"/>
- <o x="1543" c="free" o="0" r="crate" y="4235"/>
- <o x="1464" c="free" o="0" r="crate" y="4209"/>
- <o x="1396" c="free" o="0" r="crate" y="4182"/>
- <o x="1396" c="free" o="0" r="crate" y="4147"/>
- <o x="1464" c="free" o="0" r="crate" y="4078"/>
- <o x="1496" c="free" o="0" r="crate" y="4143"/>
- <o x="1686" c="free" o="0" r="crate" y="4225"/>
- <o x="1623" c="free" o="0" r="crate" y="4174"/>
- <o x="1429" c="free" o="0" r="crate" y="3943"/>
- <o x="1872" c="free" o="154" r="crate" y="4584"/>
- <o x="1913" c="free" o="11" r="crate" y="4682"/>
- <o x="2137" c="free" o="78" r="crate" y="4774"/>
- <o x="2121" c="free" o="129" r="crate" y="4682"/>
- <o x="2031" c="free" o="263" r="crate" y="4700"/>
- <o x="2058" c="free" o="131" r="crate" y="4578"/>
- <o x="1306" c="free" o="212" r="crate" y="4789"/>
- <o x="1298" c="free" o="318" r="crate" y="4892"/>
- <o x="1211" c="free" o="108" r="crate" y="4753"/>
- <o x="1366" c="free" o="346" r="crate" y="4851"/>
- <o x="1852" c="free" o="224" r="crate" y="4519"/>
- <o x="1249" c="free" o="229" r="crate" y="4830"/>
- <o x="1390" c="free" o="113" r="crate" y="4804"/>
- <o x="1077" c="free" o="271" r="crate" y="4793"/>
- <o x="1358" c="free" o="229" r="crate" y="4944"/>
- <o x="1629" c="free" o="68" r="crate" y="4251"/>
- <o x="1613" c="free" o="242" r="crate" y="4062"/>
- <o x="1933" c="free" o="136" r="crate" y="4515"/>
- <o x="1988" c="free" o="261" r="crate" y="4713"/>
- <o x="997" c="free" o="94" r="rock" y="4866"/>
- <o x="2721" c="free" o="80" r="rock" y="4280"/>
- <o x="2859" c="free" o="70" r="rock" y="4324"/>
- <o x="2683" c="free" o="91" r="rock" y="4680"/>
- <o x="2814" c="free" o="190" r="rock" y="4476"/>
- <o x="2859" c="free" o="276" r="rock" y="4514"/>
- <o x="3137" c="free" o="168" r="rock" y="5062"/>
- <o x="4211" c="free" o="194" r="rock" y="4983"/>
- <o x="3578" c="free" o="209" r="rock" y="5073"/>
- <o x="3314" c="free" o="322" r="rock" y="5456"/>
- <o x="2666" c="free" o="77" r="rock" y="4824"/>
- <o x="2042" c="free" o="159" r="rock" y="3638"/>
- <o x="1983" c="free" o="323" r="rock" y="4073"/>
- <o x="1663" c="free" o="340" r="rock" y="3670"/>
- <o x="2456" c="free" o="291" r="rock" y="3242"/>
- <o x="3059" c="free" o="47" r="rock" y="3383"/>
- <o x="2849" c="free" o="170" r="rock" y="3559"/>
- <o x="3440" c="free" o="271" r="rock" y="3639"/>
- <o x="3762" c="free" o="33" r="rock" y="3469"/>
- <o x="2562" c="free" o="267" r="rock" y="3318"/>
- <o x="2962" c="free" o="140" r="rock" y="3231"/>
- <o x="2273" c="free" o="146" r="rock" y="2649"/>
- <o x="2614" c="free" o="178" r="rock" y="2693"/>
- <o x="3014" c="free" o="241" r="rock" y="2400"/>
- <o x="1721" c="free" o="87" r="rock" y="1759"/>
- <o x="1524" c="free" o="292" r="rock" y="2031"/>
- <o x="1480" c="free" o="18" r="rock" y="2328"/>
- <o x="1583" c="free" o="348" r="rock" y="2704"/>
- <o x="2335" c="free" o="54" r="rock" y="1631"/>
- <o x="1566" c="free" o="48" r="rock" y="3228"/>
- <o x="604" c="free" o="311" r="rock" y="2783"/>
- <o x="766" c="free" o="149" r="rock" y="2345"/>
- <o x="721" c="free" o="129" r="rock" y="1393"/>
- <o x="3507" c="free" o="21" r="rock" y="1145"/>
- <o x="3442" c="free" o="240" r="rock" y="897"/>
- <o x="3500" c="free" o="319" r="rock" y="724"/>
- <o x="3273" c="free" o="169" r="rock" y="383"/>
- <o x="3597" c="free" o="48" r="rock" y="466"/>
- <o x="4269" c="free" o="25" r="rock" y="2300"/>
- <o x="4642" c="free" o="250" r="rock" y="3087"/>
- <o x="5076" c="free" o="242" r="rock" y="2987"/>
- <o x="5512" c="free" o="103" r="rock" y="2897"/>
- <o x="5107" c="free" o="281" r="rock" y="2900"/>
- <o x="5004" c="free" o="205" r="rock" y="3121"/>
- <o x="4607" c="free" o="0" r="tire" y="4133"/>
- <o x="4635" c="free" o="0" r="tire" y="4133"/>
- <o x="4674" c="free" o="0" r="tire" y="4123"/>
- <o x="4698" c="free" o="0" r="tire" y="4113"/>
- <o x="4730" c="free" o="0" r="tire" y="4106"/>
- <o x="4774" c="free" o="0" r="tire" y="4093"/>
- <o x="4797" c="free" o="0" r="tire" y="4079"/>
- <o x="4811" c="free" o="0" r="tire" y="4065"/>
- <o x="4826" c="free" o="0" r="tire" y="4043"/>
- <o x="4841" c="free" o="0" r="tire" y="4018"/>
- <o x="4848" c="free" o="0" r="tire" y="3991"/>
- <o x="4854" c="free" o="0" r="tire" y="3940"/>
- <o x="4863" c="free" o="0" r="tire" y="3910"/>
- <o x="4600" c="free" o="0" r="tire" y="4167"/>
- <o x="4639" c="free" o="0" r="tire" y="4167"/>
- <o x="4694" c="free" o="0" r="tire" y="4157"/>
- <o x="4735" c="free" o="0" r="tire" y="4146"/>
- <o x="4785" c="free" o="0" r="tire" y="4131"/>
- <o x="4841" c="free" o="0" r="tire" y="4093"/>
- <o x="4874" c="free" o="0" r="tire" y="4059"/>
- <o x="4885" c="free" o="0" r="tire" y="4010"/>
- <o x="4898" c="free" o="0" r="tire" y="3952"/>
- <o x="4705" c="free" o="0" r="tire" y="3292"/>
- <o x="4781" c="free" o="0" r="tire" y="3320"/>
- <o x="4810" c="free" o="0" r="tire" y="3345"/>
- <o x="4898" c="free" o="0" r="tire" y="3415"/>
- <o x="4904" c="free" o="0" r="tire" y="3449"/>
- <o x="4909" c="free" o="0" r="tire" y="3526"/>
- <o x="4850" c="free" o="0" r="tire" y="3388"/>
- <o x="4865" c="free" o="0" r="tire" y="3440"/>
- <o x="4831" c="free" o="0" r="tire" y="3349"/>
- <o x="4776" c="free" o="0" r="tire" y="3285"/>
- <o x="4820" c="free" o="0" r="tire" y="3304"/>
- <o x="4846" c="free" o="0" r="tire" y="3339"/>
- <o x="4874" c="free" o="0" r="tire" y="3361"/>
- <o x="4902" c="free" o="0" r="tire" y="3394"/>
- <o x="4891" c="free" o="0" r="tire" y="3484"/>
- <o x="4926" c="free" o="0" r="tire" y="3546"/>
- <o x="4906" c="free" o="0" r="tire" y="3572"/>
- <o x="4961" c="free" o="0" r="tire" y="3452"/>
- <o x="4933" c="free" o="0" r="tire" y="3480"/>
- <o x="478" c="free" o="0" r="tire" y="3853"/>
- <o x="480" c="free" o="0" r="tire" y="3913"/>
- <o x="479" c="free" o="0" r="tire" y="3941"/>
- <o x="483" c="free" o="0" r="tire" y="3966"/>
- <o x="476" c="free" o="0" r="tire" y="4026"/>
- <o x="481" c="free" o="0" r="tire" y="4067"/>
- <o x="453" c="free" o="0" r="tire" y="4087"/>
- <o x="453" c="free" o="0" r="tire" y="4050"/>
- <o x="448" c="free" o="0" r="tire" y="4006"/>
- <o x="448" c="free" o="0" r="tire" y="3913"/>
- <o x="450" c="free" o="0" r="tire" y="3853"/>
- <o x="433" c="free" o="0" r="tire" y="3949"/>
- <o x="411" c="free" o="0" r="tire" y="3979"/>
- <o x="448" c="free" o="0" r="tire" y="3965"/>
- <o x="420" c="free" o="0" r="tire" y="4011"/>
- <o x="467" c="free" o="0" r="tire" y="3992"/>
- <o x="475" c="free" o="0" r="tire" y="3881"/>
- <o x="468" c="free" o="0" r="tire" y="3811"/>
- <o x="484" c="free" o="0" r="tire" y="3336"/>
- <o x="476" c="free" o="0" r="tire" y="3394"/>
- <o x="467" c="free" o="0" r="tire" y="3450"/>
- <o x="467" c="free" o="0" r="tire" y="3544"/>
- <o x="463" c="free" o="0" r="tire" y="3602"/>
- <o x="463" c="free" o="0" r="tire" y="3654"/>
- <o x="431" c="free" o="0" r="tire" y="3668"/>
- <o x="423" c="free" o="0" r="tire" y="3705"/>
- <o x="444" c="free" o="0" r="tire" y="3771"/>
- <o x="406" c="free" o="0" r="tire" y="3839"/>
- <o x="413" c="free" o="0" r="tire" y="3875"/>
- <o x="2652" c="free" o="0" r="tire" y="468"/>
- <o x="2693" c="free" o="0" r="tire" y="474"/>
- <o x="2743" c="free" o="0" r="tire" y="500"/>
- <o x="2778" c="free" o="0" r="tire" y="554"/>
- <o x="2801" c="free" o="0" r="tire" y="604"/>
- <o x="2765" c="free" o="0" r="tire" y="533"/>
- <o x="2715" c="free" o="0" r="tire" y="494"/>
- <o x="1789" c="free" o="0" r="tire" y="678"/>
- <o x="1798" c="free" o="0" r="tire" y="630"/>
- <o x="1815" c="free" o="0" r="tire" y="584"/>
- <o x="1831" c="free" o="0" r="tire" y="553"/>
- <o x="1858" c="free" o="0" r="tire" y="532"/>
- <o x="1893" c="free" o="0" r="tire" y="510"/>
- <o x="1935" c="free" o="0" r="tire" y="493"/>
- <o x="1981" c="free" o="0" r="tire" y="483"/>
- <o x="2431" c="free" o="0" r="grandstand" y="3706"/>
- <o x="2639" c="free" o="0" r="grandstand" y="3706"/>
- <o x="2846" c="free" o="0" r="grandstand" y="3704"/>
- <o x="3081" c="free" o="0" r="grandstand" y="3702"/>
- <o x="2413" c="free" o="0" r="dustRacing2DBanner" y="3802"/>
- <o x="2680" c="free" o="0" r="dustRacing2DBanner" y="3804"/>
- <o x="2944" c="free" o="0" r="dustRacing2DBanner" y="3805"/>
- <o x="3209" c="free" o="0" r="dustRacing2DBanner" y="3805"/>
- <o x="3233" c="free" o="0" r="tire" y="3859"/>
- <o x="3267" c="free" o="0" r="tire" y="3880"/>
- <o x="3288" c="free" o="0" r="tire" y="3906"/>
- <o x="3313" c="free" o="0" r="tire" y="3932"/>
- <o x="3322" c="free" o="0" r="tire" y="3967"/>
- <o x="3328" c="free" o="0" r="tire" y="4001"/>
- <o x="3271" c="free" o="0" r="tire" y="3843"/>
- <o x="3302" c="free" o="0" r="tire" y="3867"/>
- <o x="3327" c="free" o="0" r="tire" y="3889"/>
- <o x="3357" c="free" o="0" r="tire" y="3940"/>
- <o x="3357" c="free" o="0" r="tire" y="3978"/>
- <o x="3352" c="free" o="0" r="tire" y="4039"/>
- <o x="3374" c="free" o="0" r="tire" y="4015"/>
- <o x="1202" c="free" o="0" r="tire" y="3853"/>
- <o x="1226" c="free" o="0" r="tire" y="3868"/>
- <o x="1243" c="free" o="0" r="tire" y="3885"/>
- <o x="1254" c="free" o="0" r="tire" y="3924"/>
- <o x="1254" c="free" o="0" r="tire" y="3852"/>
- <o x="1262" c="free" o="0" r="tire" y="3865"/>
- <o x="1270" c="free" o="0" r="tire" y="3888"/>
- <o x="1289" c="free" o="0" r="tire" y="3918"/>
- <o x="1285" c="free" o="0" r="tire" y="3861"/>
- <o x="1266" c="free" o="0" r="tire" y="3946"/>
- <o x="3041" c="free" o="90" r="wallLong" y="610"/>
- <o x="3042" c="free" o="90" r="wallLong" y="877"/>
- <o x="3043" c="free" o="90" r="wallLong" y="1142"/>
- <o x="2387" c="free" o="0" r="wallLong" y="2014"/>
- <o x="2527" c="free" o="90" r="wallLong" y="1874"/>
- <o x="3279" c="free" o="90" r="wallLong" y="2335"/>
- <o x="3278" c="free" o="90" r="wallLong" y="2068"/>
- <o x="3279" c="free" o="90" r="wall" y="2768"/>
- <o x="3279" c="free" o="90" r="wallLong" y="2599"/>
- <o x="3128" c="free" o="0" r="dustRacing2DBanner" y="2790"/>
- <o x="2967" c="free" o="90" r="left" y="3111"/>
- <o x="4542" c="free" o="0" r="wall" y="3592"/>
- <o x="4589" c="free" o="90" r="wall" y="3783"/>
- <o x="4588" c="free" o="90" r="wall" y="3639"/>
- <o x="4544" c="free" o="0" r="wall" y="3830"/>
- <o x="4588" c="free" o="90" r="wall" y="3714"/>
- <o x="3937" c="free" o="0" r="wall" y="4144"/>
- <o x="4016" c="free" o="0" r="wall" y="4143"/>
- <o x="4089" c="free" o="0" r="wall" y="4144"/>
- <o x="3883" c="free" o="90" r="wall" y="4187"/>
- <o x="3885" c="free" o="90" r="wall" y="4264"/>
- <o x="3453" c="free" o="0" r="dustRacing2DBanner" y="4599"/>
- <o x="3053" c="free" o="0" r="crate" y="4211"/>
- <o x="3008" c="free" o="0" r="crate" y="4189"/>
- <o x="2929" c="free" o="298" r="crate" y="4158"/>
- <o x="2987" c="free" o="120" r="crate" y="4130"/>
- <o x="3039" c="free" o="121" r="crate" y="4157"/>
- <o x="2966" c="free" o="151" r="crate" y="4207"/>
- <o x="2866" c="free" o="299" r="crate" y="4144"/>
- <o x="2938" c="free" o="196" r="crate" y="4116"/>
- <o x="2878" c="free" o="180" r="crate" y="4179"/>
- <o x="2975" c="free" o="137" r="crate" y="4300"/>
- <o x="2924" c="free" o="54" r="crate" y="4233"/>
- <o x="3024" c="free" o="9" r="crate" y="4281"/>
- <o x="2959" c="free" o="55" r="crate" y="4350"/>
- <o x="2982" c="free" o="52" r="crate" y="4258"/>
- <o x="2896" c="free" o="242" r="crate" y="4303"/>
- <o x="2793" c="free" o="329" r="crate" y="4145"/>
- <o x="2826" c="free" o="171" r="crate" y="4204"/>
- <o x="2662" c="free" o="194" r="crate" y="4180"/>
- <o x="2626" c="free" o="292" r="crate" y="4242"/>
- <o x="2622" c="free" o="60" r="crate" y="4168"/>
- <o x="2700" c="free" o="89" r="crate" y="4138"/>
- <o x="2752" c="free" o="11" r="crate" y="4183"/>
- <o x="2696" c="free" o="356" r="crate" y="4200"/>
- <o x="2654" c="free" o="322" r="crate" y="4281"/>
- <o x="2631" c="free" o="23" r="crate" y="4350"/>
- <o x="2754" c="free" o="53" r="crate" y="4229"/>
- <o x="2843" c="free" o="63" r="crate" y="4260"/>
- <o x="1883" c="free" o="32" r="crate" y="4690"/>
- <o x="1861" c="free" o="86" r="crate" y="4746"/>
- <o x="1943" c="free" o="228" r="crate" y="4749"/>
- <o x="1966" c="free" o="167" r="crate" y="4816"/>
- <o x="1896" c="free" o="333" r="crate" y="4780"/>
- <o x="2067" c="free" o="308" r="crate" y="4794"/>
- <o x="1836" c="free" o="338" r="crate" y="4612"/>
- <o x="4482" c="free" o="0" r="wallLong" y="3237"/>
- <o x="4746" c="free" o="0" r="wallLong" y="3236"/>
- <o x="5007" c="free" o="0" r="wallLong" y="3233"/>
- <o x="5505" c="free" o="-40" r="wallLong" y="3148"/>
- <o x="4409" c="free" o="0" r="rock" y="2888"/>
- <o x="4468" c="free" o="0" r="rock" y="2869"/>
- <o x="4426" c="free" o="0" r="rock" y="2990"/>
- <o x="4534" c="free" o="0" r="rock" y="2882"/>
- <o x="4591" c="free" o="0" r="rock" y="2877"/>
- <o x="4857" c="free" o="0" r="rock" y="2896"/>
- <o x="4657" c="free" o="0" r="rock" y="3174"/>
- <o x="2184" c="free" o="90" r="wallLong" y="4147"/>
- <o x="1460" c="free" o="0" r="wallLong" y="3833"/>
- <o x="1734" c="free" o="0" r="wallLong" y="3837"/>
- <o x="613" c="free" o="0" r="wallLong" y="4128"/>
- <o x="874" c="free" o="0" r="wallLong" y="4128"/>
- <o x="1286" c="free" o="180" r="wallLong" y="4691"/>
- <o x="1428" c="free" o="90" r="wallLong" y="4818"/>
- <o x="1460" c="free" o="0" r="wallLong" y="3597"/>
- <o x="2009" c="free" o="0" r="wallLong" y="3839"/>
- <o x="1616" c="free" o="0" r="wallLong" y="1027"/>
- <o x="1758" c="free" o="90" r="wallLong" y="1150"/>
- <o x="1756" c="free" o="90" r="wallLong" y="882"/>
- <o x="2203" c="free" o="0" r="dustRacing2DBanner" y="811"/>
- <o x="2521" c="free" o="90" r="wallLong" y="926"/>
- <o x="3041" c="free" o="90" r="wallLong" y="1409"/>
- <o x="3042" c="free" o="90" r="wallLong" y="1671"/>
- <o x="2845" c="free" o="0" r="brake" y="1720"/>
- <o x="2520" c="free" o="0" r="left" y="1666"/>
- <o x="2520" c="free" o="0" r="brake" y="1718"/>
- <o x="2271" c="free" o="0" r="left" y="4628"/>
- <o x="2600" c="free" o="0" r="left" y="4626"/>
- <o x="1849" c="free" o="45" r="left" y="4803"/>
- <o x="1826" c="free" o="45" r="left" y="5176"/>
- <o x="501" c="free" o="90" r="wallLong" y="4283"/>
- <o x="504" c="free" o="90" r="wallLong" y="4544"/>
- <o x="761" c="free" o="0" r="wallLong" y="4688"/>
- <o x="1021" c="free" o="0" r="wallLong" y="4690"/>
- <o x="594" c="free" o="0" r="wall" y="4688"/>
- <o x="523" c="free" o="0" r="wall" y="4686"/>
- <o x="1843" c="free" o="0" r="wallLong" y="4194"/>
- <o x="5178" c="free" o="0" r="left" y="2183"/>
- <o x="5267" c="free" o="0" r="wallLong" y="3229"/>
- <o x="2763" c="free" o="0" r="rock" y="257"/>
- <o x="3278" c="free" o="0" r="rock" y="221"/>
- <o x="3426" c="free" o="0" r="rock" y="484"/>
- <o x="563" c="free" o="289" r="rock" y="1863"/>
- <o x="321" c="free" o="146" r="rock" y="2605"/>
- <o x="352" c="free" o="156" r="rock" y="1000"/>
- <o x="2089" c="free" o="213" r="rock" y="3384"/>
- <o x="4252" c="free" o="359" r="rock" y="4605"/>
- <o x="4794" c="free" o="275" r="rock" y="4326"/>
- <o x="5078" c="free" o="331" r="rock" y="3515"/>
- <o x="4052" c="free" o="245" r="rock" y="4357"/>
- <n w="256" x="1170" i="0" h="256" y="1681"/>
- <n w="256" x="1284" i="1" h="256" y="1435"/>
- <n w="300" x="1844" i="2" h="256" y="1349"/>
- <n w="400" x="1962" i="3" h="256" y="749"/>
- <n w="256" x="2178" i="4" h="256" y="656"/>
- <n w="256" x="2532" i="5" h="256" y="648"/>
- <n w="400" x="2679" i="6" h="256" y="805"/>
- <n w="400" x="2656" i="7" h="256" y="1720"/>
- <n w="256" x="2601" i="8" h="400" y="2072"/>
- <n w="400" x="1988" i="9" h="256" y="2154"/>
- <n w="400" x="1898" i="10" h="256" y="2754"/>
- <n w="256" x="2040" i="11" h="400" y="2908"/>
- <n w="256" x="2948" i="12" h="400" y="2914"/>
- <n w="400" x="3376" i="13" h="256" y="2829"/>
- <n w="400" x="3403" i="14" h="256" y="2073"/>
- <n w="256" x="3527" i="15" h="256" y="1454"/>
- <n w="256" x="3887" i="16" h="256" y="1441"/>
- <n w="256" x="4054" i="17" h="366" y="1871"/>
- <n w="400" x="4405" i="18" h="256" y="1876"/>
- <n w="256" x="4552" i="19" h="256" y="1448"/>
- <n w="400" x="4948" i="20" h="256" y="1476"/>
- <n w="300" x="5009" i="21" h="256" y="2160"/>
- <n w="256" x="4886" i="22" h="400" y="2616"/>
- <n w="256" x="4234" i="23" h="256" y="2806"/>
- <n w="256" x="4214" i="24" h="256" y="3282"/>
- <n w="256" x="4505" i="25" h="256" y="3446"/>
- <n w="256" x="4752" i="26" h="256" y="3690"/>
- <n w="256" x="4534" i="27" h="333" y="4021"/>
- <n w="300" x="3738" i="28" h="256" y="4045"/>
- <n w="256" x="3642" i="29" h="400" y="4706"/>
- <n w="400" x="3250" i="30" h="256" y="4650"/>
- <n w="400" x="3133" i="31" h="256" y="4056"/>
- <n w="256" x="2530" i="32" h="256" y="4013"/>
- <n w="340" x="2390" i="33" h="256" y="4421"/>
- <n w="256" x="2316" i="34" h="400" y="4925"/>
- <n w="500" x="1786" i="35" h="256" y="4905"/>
- <n w="300" x="1581" i="36" h="456" y="4544"/>
- <n w="300" x="1198" i="37" h="256" y="4373"/>
- <n w="400" x="1100" i="38" h="256" y="4025"/>
- <n w="256" x="667" i="39" h="256" y="3900"/>
- <n w="400" x="707" i="40" h="256" y="3532"/>
- <n w="400" x="1082" i="41" h="256" y="3379"/>
- <n w="256" x="1152" i="42" h="256" y="2429"/>
- <n w="256" x="1151" i="43" h="256" y="2068"/>
- <n w="256" x="1170" i="44" h="256" y="1681"/>
+<track version="2.0.1" index="13" cols="22" name="Desert Storm" rows="22">
+ <t o="0" i="0" t="sand" j="0"/>
+ <t o="0" i="0" t="sand" j="1"/>
+ <t o="0" i="0" t="sand" j="2"/>
+ <t o="0" i="0" t="sand" j="3"/>
+ <t o="0" i="0" t="sand" j="4"/>
+ <t o="0" i="0" t="sand" j="5"/>
+ <t o="0" i="0" t="sand" j="6"/>
+ <t o="0" i="0" t="sand" j="7"/>
+ <t o="0" i="0" t="sand" j="8"/>
+ <t o="0" i="0" t="sand" j="9"/>
+ <t o="0" i="0" t="sand" j="10"/>
+ <t o="0" i="0" t="sand" j="11"/>
+ <t o="0" i="0" t="sand" j="12"/>
+ <t o="0" i="0" t="sand" j="13"/>
+ <t o="0" i="0" t="sand" j="14"/>
+ <t o="0" i="0" t="sand" j="15"/>
+ <t o="0" i="0" t="sand" j="16"/>
+ <t o="0" i="0" t="sand" j="17"/>
+ <t o="0" i="0" t="sand" j="18"/>
+ <t o="0" i="0" t="sand" j="19"/>
+ <t o="0" i="0" t="sand" j="20"/>
+ <t o="0" i="0" t="sand" j="21"/>
+ <t o="0" i="1" t="sand" j="0"/>
+ <t o="0" i="1" t="sand" j="1"/>
+ <t o="0" i="1" t="sand" j="2"/>
+ <t o="0" i="1" t="sand" j="3"/>
+ <t o="0" i="1" t="sand" j="4"/>
+ <t o="0" i="1" t="sand" j="5"/>
+ <t o="0" i="1" t="sand" j="6"/>
+ <t o="0" i="1" t="sand" j="7"/>
+ <t o="0" i="1" t="sand" j="8"/>
+ <t o="0" i="1" t="sand" j="9"/>
+ <t o="0" i="1" t="sand" j="10"/>
+ <t o="0" i="1" t="sand" j="11"/>
+ <t o="180" i="1" t="sandGrassCorner2" j="12"/>
+ <t o="90" i="1" t="sandGrassStraight" j="13"/>
+ <t o="90" i="1" t="sandGrassStraight" j="14"/>
+ <t o="90" i="1" t="sandGrassStraight" j="15"/>
+ <t o="90" i="1" t="sandGrassCorner2" j="16"/>
+ <t o="0" i="1" t="sand" j="17"/>
+ <t o="0" i="1" t="sand" j="18"/>
+ <t o="0" i="1" t="sand" j="19"/>
+ <t o="0" i="1" t="sand" j="20"/>
+ <t o="0" i="1" t="sand" j="21"/>
+ <t o="0" i="2" t="sand" j="0"/>
+ <t o="0" i="2" t="sand" j="1"/>
+ <t o="0" i="2" t="sand" j="2"/>
+ <t o="0" i="2" t="sand" j="3"/>
+ <t o="0" i="2" t="sand" j="4"/>
+ <t o="0" i="2" t="sand" j="5"/>
+ <t o="0" i="2" t="sand" j="6"/>
+ <t o="0" i="2" t="sand" j="7"/>
+ <t o="0" i="2" t="sand" j="8"/>
+ <t o="0" i="2" t="sand" j="9"/>
+ <t o="0" i="2" t="sand" j="10"/>
+ <t o="0" i="2" t="sand" j="11"/>
+ <t o="180" i="2" t="sandGrassStraight" j="12"/>
+ <t o="0" i="2" t="corner90" j="13"/>
+ <t o="0" i="2" t="straight" j="14"/>
+ <t o="270" i="2" t="corner90" j="15"/>
+ <t o="0" i="2" t="sandGrassStraight" j="16"/>
+ <t o="0" i="2" t="sand" j="17"/>
+ <t o="0" i="2" t="sand" j="18"/>
+ <t o="0" i="2" t="sand" j="19"/>
+ <t o="0" i="2" t="sand" j="20"/>
+ <t o="0" i="2" t="sand" j="21"/>
+ <t o="0" i="3" t="sand" j="0"/>
+ <t o="0" i="3" t="sand" j="1"/>
+ <t o="0" i="3" t="sand" j="2"/>
+ <t o="0" i="3" t="sand" j="3"/>
+ <t o="180" i="3" t="sandGrassCorner2" j="4"/>
+ <t o="90" i="3" t="sandGrassStraight" j="5"/>
+ <t o="90" i="3" t="sandGrassStraight" j="6"/>
+ <t o="90" i="3" t="sandGrassStraight" j="7"/>
+ <t o="90" i="3" t="sandGrassStraight" j="8"/>
+ <t o="90" i="3" t="sandGrassStraight" j="9"/>
+ <t o="90" i="3" t="sandGrassStraight" j="10"/>
+ <t o="90" i="3" t="sandGrassStraight" j="11"/>
+ <t o="180" i="3" t="sandGrassCorner" j="12"/>
+ <t o="90" i="3" t="straight" j="13"/>
+ <t o="0" i="3" t="grass" j="14"/>
+ <t o="90" i="3" t="straight" j="15"/>
+ <t o="90" i="3" t="sandGrassCorner" j="16"/>
+ <t o="90" i="3" t="sandGrassStraight" j="17"/>
+ <t o="90" i="3" t="sandGrassCorner2" j="18"/>
+ <t o="0" i="3" t="sand" j="19"/>
+ <t o="0" i="3" t="sand" j="20"/>
+ <t o="0" i="3" t="sand" j="21"/>
+ <t o="0" i="4" t="sand" j="0"/>
+ <t o="0" i="4" t="sand" j="1"/>
+ <t o="0" i="4" t="sand" j="2"/>
+ <t o="0" i="4" t="sand" j="3"/>
+ <t o="180" i="4" t="sandGrassStraight" j="4"/>
+ <t o="0" i="4" t="corner90" j="5"/>
+ <t o="0" c="1" i="4" t="straight" j="6"/>
+ <t o="0" i="4" t="finish" j="7"/>
+ <t o="0" i="4" t="straight" j="8"/>
+ <t o="0" i="4" t="straight" j="9"/>
+ <t o="0" i="4" t="straight" j="10"/>
+ <t o="0" i="4" t="straight" j="11"/>
+ <t o="0" i="4" t="straight" j="12"/>
+ <t o="180" i="4" t="corner90" j="13"/>
+ <t o="0" i="4" t="grass" j="14"/>
+ <t o="90" i="4" t="corner90" j="15"/>
+ <t o="0" i="4" t="straight" j="16"/>
+ <t o="-90" i="4" t="corner90" j="17"/>
+ <t o="0" i="4" t="sandGrassStraight" j="18"/>
+ <t o="0" i="4" t="sand" j="19"/>
+ <t o="0" i="4" t="sand" j="20"/>
+ <t o="0" i="4" t="sand" j="21"/>
+ <t o="0" i="5" t="sand" j="0"/>
+ <t o="0" i="5" t="sand" j="1"/>
+ <t o="0" i="5" t="sand" j="2"/>
+ <t o="0" i="5" t="sand" j="3"/>
+ <t o="180" i="5" t="sandGrassStraight" j="4"/>
+ <t o="90" i="5" t="straight" j="5"/>
+ <t o="0" i="5" t="sandGrassCorner" j="6"/>
+ <t o="270" i="5" t="sandGrassStraight" j="7"/>
+ <t o="-90" i="5" t="sandGrassStraight" j="8"/>
+ <t o="-90" i="5" t="sandGrassStraight" j="9"/>
+ <t o="270" i="5" t="sandGrassStraight" j="10"/>
+ <t o="-90" i="5" t="sandGrassStraight" j="11"/>
+ <t o="-90" i="5" t="sandGrassStraight" j="12"/>
+ <t o="270" i="5" t="sandGrassStraight" j="13"/>
+ <t o="270" i="5" t="sandGrassStraight" j="14"/>
+ <t o="270" i="5" t="sandGrassStraight" j="15"/>
+ <t o="270" i="5" t="sandGrassCorner" j="16"/>
+ <t o="90" i="5" t="straight" j="17"/>
+ <t o="90" i="5" t="sandGrassCorner" j="18"/>
+ <t o="90" i="5" t="sandGrassStraight" j="19"/>
+ <t o="90" i="5" t="sandGrassCorner2" j="20"/>
+ <t o="0" i="5" t="sand" j="21"/>
+ <t o="0" i="6" t="sand" j="0"/>
+ <t o="180" i="6" t="sandGrassCorner2" j="1"/>
+ <t o="90" i="6" t="sandGrassStraight" j="2"/>
+ <t o="90" i="6" t="sandGrassStraight" j="3"/>
+ <t o="180" i="6" t="sandGrassCorner" j="4"/>
+ <t o="90" i="6" t="straight" j="5"/>
+ <t o="0" i="6" t="sandGrassStraight" j="6"/>
+ <t o="180" i="6" t="sandGrassCorner2" j="7"/>
+ <t o="90" i="6" t="sandGrassStraight" j="8"/>
+ <t o="90" i="6" t="sandGrassStraight" j="9"/>
+ <t o="90" i="6" t="sandGrassStraight" j="10"/>
+ <t o="90" i="6" t="sandGrassStraight" j="11"/>
+ <t o="90" i="6" t="sandGrassCorner2" j="12"/>
+ <t o="0" i="6" t="sand" j="13"/>
+ <t o="0" i="6" t="sand" j="14"/>
+ <t o="0" i="6" t="sand" j="15"/>
+ <t o="180" i="6" t="sandGrassStraight" j="16"/>
+ <t o="90" i="6" t="corner90" j="17"/>
+ <t o="0" i="6" t="straight" j="18"/>
+ <t o="270" i="6" t="corner90" j="19"/>
+ <t o="0" i="6" t="sandGrassStraight" j="20"/>
+ <t o="0" i="6" t="sand" j="21"/>
+ <t o="0" i="7" t="sand" j="0"/>
+ <t o="180" i="7" t="sandGrassStraight" j="1"/>
+ <t o="0" i="7" t="corner90" j="2"/>
+ <t o="0" i="7" t="straight" j="3"/>
+ <t o="0" i="7" t="straight" j="4"/>
+ <t o="180" i="7" t="corner90" j="5"/>
+ <t o="0" i="7" t="sandGrassStraight" j="6"/>
+ <t o="180" i="7" t="sandGrassStraight" j="7"/>
+ <t o="0" i="7" t="corner90" j="8"/>
+ <t o="0" i="7" t="straight" j="9"/>
+ <t o="0" i="7" t="straight" j="10"/>
+ <t o="270" i="7" t="corner90" j="11"/>
+ <t o="0" i="7" t="sandGrassStraight" j="12"/>
+ <t o="0" i="7" t="sand" j="13"/>
+ <t o="0" i="7" t="sand" j="14"/>
+ <t o="0" i="7" t="sand" j="15"/>
+ <t o="270" i="7" t="sandGrassCorner2" j="16"/>
+ <t o="270" i="7" t="sandGrassStraight" j="17"/>
+ <t o="270" i="7" t="sandGrassCorner" j="18"/>
+ <t o="90" i="7" t="straight" j="19"/>
+ <t o="0" i="7" t="sandGrassStraight" j="20"/>
+ <t o="0" i="7" t="sand" j="21"/>
+ <t o="0" i="8" t="sand" j="0"/>
+ <t o="180" i="8" t="sandGrassStraight" j="1"/>
+ <t o="90" i="8" t="straight" j="2"/>
+ <t o="0" i="8" t="sandGrassCorner" j="3"/>
+ <t o="-90" i="8" t="sandGrassStraight" j="4"/>
+ <t o="-90" i="8" t="sandGrassStraight" j="5"/>
+ <t o="0" i="8" t="sandGrassCorner2" j="6"/>
+ <t o="180" i="8" t="sandGrassStraight" j="7"/>
+ <t o="90" i="8" t="straight" j="8"/>
+ <t o="360" i="8" t="sandGrassCorner" j="9"/>
+ <t o="270" i="8" t="sandGrassCorner" j="10"/>
+ <t o="90" i="8" t="straight" j="11"/>
+ <t o="0" i="8" t="sandGrassStraight" j="12"/>
+ <t o="0" i="8" t="sand" j="13"/>
+ <t o="180" i="8" t="sandGrassCorner2" j="14"/>
+ <t o="90" i="8" t="sandGrassStraight" j="15"/>
+ <t o="90" i="8" t="sandGrassStraight" j="16"/>
+ <t o="90" i="8" t="sandGrassStraight" j="17"/>
+ <t o="180" i="8" t="sandGrassCorner" j="18"/>
+ <t o="90" i="8" t="straight" j="19"/>
+ <t o="0" i="8" t="sandGrassStraight" j="20"/>
+ <t o="0" i="8" t="sand" j="21"/>
+ <t o="0" i="9" t="sand" j="0"/>
+ <t o="180" i="9" t="sandGrassStraight" j="1"/>
+ <t o="90" i="9" t="straight" j="2"/>
+ <t o="90" i="9" t="sandGrassCorner" j="3"/>
+ <t o="90" i="9" t="sandGrassStraight" j="4"/>
+ <t o="90" i="9" t="sandGrassStraight" j="5"/>
+ <t o="90" i="9" t="sandGrassStraight" j="6"/>
+ <t o="180" i="9" t="sandGrassCorner" j="7"/>
+ <t o="90" i="9" t="straight" j="8"/>
+ <t o="0" i="9" t="sandGrassStraight" j="9"/>
+ <t o="180" i="9" t="sandGrassStraight" j="10"/>
+ <t o="90" i="9" t="straight" j="11"/>
+ <t o="0" i="9" t="sandGrassStraight" j="12"/>
+ <t o="0" i="9" t="sand" j="13"/>
+ <t o="180" i="9" t="sandGrassStraight" j="14"/>
+ <t o="0" i="9" t="corner90" j="15"/>
+ <t o="0" i="9" t="straight" j="16"/>
+ <t o="0" i="9" t="straight" j="17"/>
+ <t o="0" c="2" i="9" t="straight" j="18"/>
+ <t o="-180" i="9" t="corner90" j="19"/>
+ <t o="0" i="9" t="sandGrassStraight" j="20"/>
+ <t o="0" i="9" t="sand" j="21"/>
+ <t o="0" i="10" t="sand" j="0"/>
+ <t o="180" i="10" t="sandGrassStraight" j="1"/>
+ <t o="90" i="10" t="corner90" j="2"/>
+ <t o="0" i="10" t="straight" j="3"/>
+ <t o="0" i="10" t="straight" j="4"/>
+ <t o="0" i="10" t="straight" j="5"/>
+ <t o="0" c="2" i="10" t="straight" j="6"/>
+ <t o="0" c="2" i="10" t="straight" j="7"/>
+ <t o="180" i="10" t="corner90" j="8"/>
+ <t o="0" i="10" t="sandGrassStraight" j="9"/>
+ <t o="180" i="10" t="sandGrassStraight" j="10"/>
+ <t o="90" i="10" t="straight" j="11"/>
+ <t o="0" i="10" t="sandGrassStraight" j="12"/>
+ <t o="0" i="10" t="sand" j="13"/>
+ <t o="180" i="10" t="sandGrassStraight" j="14"/>
+ <t o="90" c="2" i="10" t="straight" j="15"/>
+ <t o="0" i="10" t="sandGrassCorner" j="16"/>
+ <t o="-90" i="10" t="sandGrassStraight" j="17"/>
+ <t o="-90" i="10" t="sandGrassStraight" j="18"/>
+ <t o="-90" i="10" t="sandGrassStraight" j="19"/>
+ <t o="0" i="10" t="sandGrassCorner2" j="20"/>
+ <t o="0" i="10" t="sand" j="21"/>
+ <t o="0" i="11" t="sand" j="0"/>
+ <t o="270" i="11" t="sandGrassCorner2" j="1"/>
+ <t o="-90" i="11" t="sandGrassStraight" j="2"/>
+ <t o="-90" i="11" t="sandGrassStraight" j="3"/>
+ <t o="-90" i="11" t="sandGrassStraight" j="4"/>
+ <t o="-90" i="11" t="sandGrassStraight" j="5"/>
+ <t o="-90" i="11" t="sandGrassStraight" j="6"/>
+ <t o="-90" i="11" t="sandGrassStraight" j="7"/>
+ <t o="-90" i="11" t="sandGrassStraight" j="8"/>
+ <t o="0" i="11" t="sandGrassCorner2" j="9"/>
+ <t o="180" i="11" t="sandGrassStraight" j="10"/>
+ <t o="270" i="11" t="straight" j="11"/>
+ <t o="0" i="11" t="sandGrassStraight" j="12"/>
+ <t o="0" i="11" t="sand" j="13"/>
+ <t o="180" i="11" t="sandGrassStraight" j="14"/>
+ <t o="90" i="11" t="straight" j="15"/>
+ <t o="90" i="11" t="sandGrassCorner" j="16"/>
+ <t o="90" i="11" t="sandGrassStraight" j="17"/>
+ <t o="90" i="11" t="sandGrassStraight" j="18"/>
+ <t o="90" i="11" t="sandGrassCorner2" j="19"/>
+ <t o="0" i="11" t="sand" j="20"/>
+ <t o="0" i="11" t="sand" j="21"/>
+ <t o="0" i="12" t="sand" j="0"/>
+ <t o="0" i="12" t="sand" j="1"/>
+ <t o="0" i="12" t="sand" j="2"/>
+ <t o="0" i="12" t="sand" j="3"/>
+ <t o="180" i="12" t="sandGrassCorner2" j="4"/>
+ <t o="90" i="12" t="sandGrassStraight" j="5"/>
+ <t o="90" i="12" t="sandGrassStraight" j="6"/>
+ <t o="90" i="12" t="sandGrassStraight" j="7"/>
+ <t o="90" i="12" t="sandGrassStraight" j="8"/>
+ <t o="90" i="12" t="sandGrassStraight" j="9"/>
+ <t o="180" i="12" t="sandGrassCorner" j="10"/>
+ <t o="90" c="2" i="12" t="straight" j="11"/>
+ <t o="0" i="12" t="sandGrassStraight" j="12"/>
+ <t o="0" i="12" t="sand" j="13"/>
+ <t o="180" i="12" t="sandGrassStraight" j="14"/>
+ <t o="90" i="12" t="corner90" j="15"/>
+ <t o="0" i="12" t="straight" j="16"/>
+ <t o="180" i="12" t="straight" j="17"/>
+ <t o="270" i="12" t="corner90" j="18"/>
+ <t o="0" i="12" t="sandGrassStraight" j="19"/>
+ <t o="0" i="12" t="sand" j="20"/>
+ <t o="0" i="12" t="sand" j="21"/>
+ <t o="0" i="13" t="sand" j="0"/>
+ <t o="0" i="13" t="sand" j="1"/>
+ <t o="0" i="13" t="sand" j="2"/>
+ <t o="0" i="13" t="sand" j="3"/>
+ <t o="-180" i="13" t="sandGrassStraight" j="4"/>
+ <t o="0" i="13" t="corner90" j="5"/>
+ <t o="0" c="2" i="13" t="straight" j="6"/>
+ <t o="0" i="13" t="straight" j="7"/>
+ <t o="0" i="13" t="straight" j="8"/>
+ <t o="0" i="13" t="straight" j="9"/>
+ <t o="0" i="13" t="straight" j="10"/>
+ <t o="-180" i="13" t="corner90" j="11"/>
+ <t o="0" i="13" t="sandGrassStraight" j="12"/>
+ <t o="0" i="13" t="sand" j="13"/>
+ <t o="180" i="13" t="sandGrassStraight" j="14"/>
+ <t o="0" i="13" t="grass" j="15"/>
+ <t o="0" i="13" t="grass" j="16"/>
+ <t o="0" i="13" t="grass" j="17"/>
+ <t o="90" i="13" t="straight" j="18"/>
+ <t o="0" i="13" t="sandGrassStraight" j="19"/>
+ <t o="0" i="13" t="sand" j="20"/>
+ <t o="0" i="13" t="sand" j="21"/>
+ <t o="0" i="14" t="sand" j="0"/>
+ <t o="0" i="14" t="sand" j="1"/>
+ <t o="0" i="14" t="sand" j="2"/>
+ <t o="0" i="14" t="sand" j="3"/>
+ <t o="180" i="14" t="sandGrassStraight" j="4"/>
+ <t o="90" i="14" t="straight" j="5"/>
+ <t o="0" i="14" t="grass" j="6"/>
+ <t o="0" i="14" t="grass" j="7"/>
+ <t o="0" i="14" t="sandGrassCorner" j="8"/>
+ <t o="-90" i="14" t="sandGrassStraight" j="9"/>
+ <t o="-90" i="14" t="sandGrassStraight" j="10"/>
+ <t o="-90" i="14" t="sandGrassStraight" j="11"/>
+ <t o="0" i="14" t="sandGrassCorner2" j="12"/>
+ <t o="0" i="14" t="sand" j="13"/>
+ <t o="180" i="14" t="sandGrassStraight" j="14"/>
+ <t o="0" i="14" t="corner90" j="15"/>
+ <t o="0" i="14" t="straight" j="16"/>
+ <t o="0" c="2" i="14" t="straight" j="17"/>
+ <t o="180" i="14" t="corner90" j="18"/>
+ <t o="0" i="14" t="sandGrassStraight" j="19"/>
+ <t o="0" i="14" t="sand" j="20"/>
+ <t o="0" i="14" t="sand" j="21"/>
+ <t o="0" i="15" t="sand" j="0"/>
+ <t o="0" i="15" t="sand" j="1"/>
+ <t o="0" i="15" t="sand" j="2"/>
+ <t o="0" i="15" t="sand" j="3"/>
+ <t o="180" i="15" t="sandGrassStraight" j="4"/>
+ <t o="90" i="15" t="corner90" j="5"/>
+ <t o="0" i="15" t="straight" j="6"/>
+ <t o="270" i="15" t="corner90" j="7"/>
+ <t o="0" i="15" t="sandGrassStraight" j="8"/>
+ <t o="180" i="15" t="sandGrassCorner2" j="9"/>
+ <t o="90" i="15" t="sandGrassStraight" j="10"/>
+ <t o="90" i="15" t="sandGrassStraight" j="11"/>
+ <t o="90" i="15" t="sandGrassStraight" j="12"/>
+ <t o="90" i="15" t="sandGrassStraight" j="13"/>
+ <t o="180" i="15" t="sandGrassCorner" j="14"/>
+ <t o="90" c="1" i="15" t="straight" j="15"/>
+ <t o="0" i="15" t="sandGrassCorner" j="16"/>
+ <t o="-90" i="15" t="sandGrassStraight" j="17"/>
+ <t o="-90" i="15" t="sandGrassStraight" j="18"/>
+ <t o="0" i="15" t="sandGrassCorner2" j="19"/>
+ <t o="0" i="15" t="sand" j="20"/>
+ <t o="0" i="15" t="sand" j="21"/>
+ <t o="0" i="16" t="sand" j="0"/>
+ <t o="0" i="16" t="sand" j="1"/>
+ <t o="0" i="16" t="sand" j="2"/>
+ <t o="0" i="16" t="sand" j="3"/>
+ <t o="180" i="16" t="sandGrassStraight" j="4"/>
+ <t o="0" i="16" t="grass" j="5"/>
+ <t o="0" i="16" t="grass" j="6"/>
+ <t o="90" i="16" t="straight" j="7"/>
+ <t o="0" i="16" t="sandGrassStraight" j="8"/>
+ <t o="180" i="16" t="sandGrassStraight" j="9"/>
+ <t o="0" i="16" t="corner90" j="10"/>
+ <t o="0" i="16" t="straight" j="11"/>
+ <t o="0" c="2" i="16" t="straight" j="12"/>
+ <t o="270" i="16" t="corner90" j="13"/>
+ <t o="0" i="16" t="grass" j="14"/>
+ <t o="90" i="16" t="straight" j="15"/>
+ <t o="0" i="16" t="sandGrassStraight" j="16"/>
+ <t o="0" i="16" t="sand" j="17"/>
+ <t o="0" i="16" t="sand" j="18"/>
+ <t o="0" i="16" t="sand" j="19"/>
+ <t o="0" i="16" t="sand" j="20"/>
+ <t o="0" i="16" t="sand" j="21"/>
+ <t o="0" i="17" t="sand" j="0"/>
+ <t o="0" i="17" t="sand" j="1"/>
+ <t o="0" i="17" t="sand" j="2"/>
+ <t o="0" i="17" t="sand" j="3"/>
+ <t o="180" i="17" t="sandGrassStraight" j="4"/>
+ <t o="0" i="17" t="corner90" j="5"/>
+ <t o="0" i="17" t="straight" j="6"/>
+ <t o="180" i="17" t="corner90" j="7"/>
+ <t o="0" i="17" t="sandGrassStraight" j="8"/>
+ <t o="180" i="17" t="sandGrassStraight" j="9"/>
+ <t o="90" c="2" i="17" t="straight" j="10"/>
+ <t o="0" i="17" t="sandGrassCorner" j="11"/>
+ <t o="270" i="17" t="sandGrassCorner" j="12"/>
+ <t o="90" i="17" t="straight" j="13"/>
+ <t o="0" i="17" t="grass" j="14"/>
+ <t o="90" i="17" t="straight" j="15"/>
+ <t o="0" i="17" t="sandGrassStraight" j="16"/>
+ <t o="0" i="17" t="sand" j="17"/>
+ <t o="0" i="17" t="sand" j="18"/>
+ <t o="0" i="17" t="sand" j="19"/>
+ <t o="0" i="17" t="sand" j="20"/>
+ <t o="0" i="17" t="sand" j="21"/>
+ <t o="0" i="18" t="sand" j="0"/>
+ <t o="0" i="18" t="sand" j="1"/>
+ <t o="0" i="18" t="sand" j="2"/>
+ <t o="0" i="18" t="sand" j="3"/>
+ <t o="180" i="18" t="sandGrassStraight" j="4"/>
+ <t o="90" i="18" t="straight" j="5"/>
+ <t o="0" i="18" t="grass" j="6"/>
+ <t o="0" i="18" t="grass" j="7"/>
+ <t o="90" i="18" t="sandGrassCorner" j="8"/>
+ <t o="180" i="18" t="sandGrassCorner" j="9"/>
+ <t o="90" i="18" t="straight" j="10"/>
+ <t o="0" i="18" t="sandGrassStraight" j="11"/>
+ <t o="180" i="18" t="sandGrassStraight" j="12"/>
+ <t o="90" i="18" t="corner90" j="13"/>
+ <t o="0" i="18" t="straight" j="14"/>
+ <t o="180" i="18" t="corner90" j="15"/>
+ <t o="0" i="18" t="sandGrassStraight" j="16"/>
+ <t o="0" i="18" t="sand" j="17"/>
+ <t o="0" i="18" t="sand" j="18"/>
+ <t o="0" i="18" t="sand" j="19"/>
+ <t o="0" i="18" t="sand" j="20"/>
+ <t o="0" i="18" t="sand" j="21"/>
+ <t o="0" i="19" t="sand" j="0"/>
+ <t o="0" i="19" t="sand" j="1"/>
+ <t o="0" i="19" t="sand" j="2"/>
+ <t o="0" i="19" t="sand" j="3"/>
+ <t o="180" i="19" t="sandGrassStraight" j="4"/>
+ <t o="90" i="19" t="corner90" j="5"/>
+ <t o="0" i="19" t="straight" j="6"/>
+ <t o="0" i="19" t="straight" j="7"/>
+ <t o="0" i="19" t="straight" j="8"/>
+ <t o="0" c="1" i="19" t="straight" j="9"/>
+ <t o="180" i="19" t="corner90" j="10"/>
+ <t o="0" i="19" t="sandGrassStraight" j="11"/>
+ <t o="270" i="19" t="sandGrassCorner2" j="12"/>
+ <t o="270" i="19" t="sandGrassStraight" j="13"/>
+ <t o="-90" i="19" t="sandGrassStraight" j="14"/>
+ <t o="-90" i="19" t="sandGrassStraight" j="15"/>
+ <t o="0" i="19" t="sandGrassCorner2" j="16"/>
+ <t o="0" i="19" t="sand" j="17"/>
+ <t o="0" i="19" t="sand" j="18"/>
+ <t o="0" i="19" t="sand" j="19"/>
+ <t o="0" i="19" t="sand" j="20"/>
+ <t o="0" i="19" t="sand" j="21"/>
+ <t o="0" i="20" t="sand" j="0"/>
+ <t o="0" i="20" t="sand" j="1"/>
+ <t o="0" i="20" t="sand" j="2"/>
+ <t o="0" i="20" t="sand" j="3"/>
+ <t o="270" i="20" t="sandGrassCorner2" j="4"/>
+ <t o="270" i="20" t="sandGrassStraight" j="5"/>
+ <t o="270" i="20" t="sandGrassStraight" j="6"/>
+ <t o="-90" i="20" t="sandGrassStraight" j="7"/>
+ <t o="-90" i="20" t="sandGrassStraight" j="8"/>
+ <t o="-90" i="20" t="sandGrassStraight" j="9"/>
+ <t o="-90" i="20" t="sandGrassStraight" j="10"/>
+ <t o="0" i="20" t="sandGrassCorner2" j="11"/>
+ <t o="0" i="20" t="sand" j="12"/>
+ <t o="0" i="20" t="sand" j="13"/>
+ <t o="0" i="20" t="sand" j="14"/>
+ <t o="0" i="20" t="sand" j="15"/>
+ <t o="0" i="20" t="sand" j="16"/>
+ <t o="0" i="20" t="sand" j="17"/>
+ <t o="0" i="20" t="sand" j="18"/>
+ <t o="0" i="20" t="sand" j="19"/>
+ <t o="0" i="20" t="sand" j="20"/>
+ <t o="0" i="20" t="sand" j="21"/>
+ <t o="0" i="21" t="sand" j="0"/>
+ <t o="0" i="21" t="sand" j="1"/>
+ <t o="0" i="21" t="sand" j="2"/>
+ <t o="0" i="21" t="sand" j="3"/>
+ <t o="0" i="21" t="sand" j="4"/>
+ <t o="0" i="21" t="sand" j="5"/>
+ <t o="0" i="21" t="sand" j="6"/>
+ <t o="0" i="21" t="sand" j="7"/>
+ <t o="0" i="21" t="sand" j="8"/>
+ <t o="0" i="21" t="sand" j="9"/>
+ <t o="0" i="21" t="sand" j="10"/>
+ <t o="0" i="21" t="sand" j="11"/>
+ <t o="90" i="21" t="sand" j="12"/>
+ <t o="0" i="21" t="sand" j="13"/>
+ <t o="0" i="21" t="sand" j="14"/>
+ <t o="0" i="21" t="sand" j="15"/>
+ <t o="0" i="21" t="sand" j="16"/>
+ <t o="0" i="21" t="sand" j="17"/>
+ <t o="0" i="21" t="sand" j="18"/>
+ <t o="0" i="21" t="sand" j="19"/>
+ <t o="0" i="21" t="sand" j="20"/>
+ <t o="0" i="21" t="sand" j="21"/>
+ <o o="90" r="pit" c="free" x="1081" y="1659"/>
+ <o o="0" r="sandAreaCurve" c="free" x="791" y="3606"/>
+ <o o="270" r="sandAreaCurve" c="free" x="791" y="3814"/>
+ <o o="90" r="wallLong" c="free" x="3572" y="4192"/>
+ <o o="90" r="wallLong" c="free" x="3573" y="4450"/>
+ <o o="90" r="wall" c="free" x="3572" y="4022"/>
+ <o o="110" r="wall" c="free" x="3585" y="3946"/>
+ <o o="140" r="wall" c="free" x="3631" y="3867"/>
+ <o o="180" r="grandstand" c="free" x="4159" y="3648"/>
+ <o o="180" r="grandstand" c="free" x="4294" y="3647"/>
+ <o o="180" r="grandstand" c="free" x="4430" y="3645"/>
+ <o o="0" r="grandstand" c="free" x="4156" y="3785"/>
+ <o o="0" r="grandstand" c="free" x="4297" y="3779"/>
+ <o o="0" r="grandstand" c="free" x="4430" y="3779"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="3836" y="3789"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="4224" y="1776"/>
+ <o o="90" r="dustRacing2DBanner" c="free" x="4113" y="1624"/>
+ <o o="270" r="dustRacing2DBanner" c="free" x="4332" y="1630"/>
+ <o o="90" r="wallLong" c="free" x="4107" y="1362"/>
+ <o o="90" r="wallLong" c="free" x="4341" y="1367"/>
+ <o o="90" r="dustRacing2DBanner" c="free" x="4625" y="1663"/>
+ <o o="90" r="dustRacing2DBanner" c="free" x="4625" y="1926"/>
+ <o o="180" r="grandstand" c="free" x="4712" y="1597"/>
+ <o o="270" r="grandstand" c="free" x="4799" y="1776"/>
+ <o o="-90" r="grandstand" c="free" x="4799" y="1944"/>
+ <o o="0" r="wallLong" c="free" x="930" y="3829"/>
+ <o o="0" r="wallLong" c="free" x="1188" y="3829"/>
+ <o o="0" r="wallLong" c="free" x="927" y="3596"/>
+ <o o="0" r="wallLong" c="free" x="1186" y="3596"/>
+ <o o="90" r="wall" c="free" x="807" y="3641"/>
+ <o o="90" r="wall" c="free" x="808" y="3711"/>
+ <o o="90" r="wall" c="free" x="808" y="3780"/>
+ <o o="0" r="bushArea" c="free" x="3451" y="4123"/>
+ <o o="0" r="plant" c="free" x="4241" y="1547"/>
+ <o o="0" r="plant" c="free" x="4818" y="1603"/>
+ <o o="90" r="dustRacing2DBanner" c="free" x="3603" y="1995"/>
+ <o o="90" r="dustRacing2DBanner" c="free" x="3603" y="1726"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="3710" y="1565"/>
+ <o o="270" r="right" c="free" x="2968" y="2778"/>
+ <o o="0" r="right" c="free" x="3295" y="1656"/>
+ <o o="0" r="right" c="free" x="2105" y="2641"/>
+ <o o="270" r="left" c="free" x="2123" y="1989"/>
+ <o o="0" r="left" c="free" x="2847" y="1669"/>
+ <o o="0" r="right" c="free" x="2078" y="958"/>
+ <o o="0" r="right" c="free" x="2079" y="1021"/>
+ <o o="0" r="right" c="free" x="3296" y="1723"/>
+ <o o="90" r="right" c="free" x="4757" y="1243"/>
+ <o o="0" r="left" c="free" x="4805" y="2191"/>
+ <o o="270" r="left" c="free" x="4570" y="3290"/>
+ <o o="-90" r="left" c="free" x="4516" y="3290"/>
+ <o o="0" r="left" c="free" x="3870" y="4486"/>
+ <o o="0" r="left" c="free" x="3873" y="4430"/>
+ <o o="0" r="brake" c="free" x="1336" y="1848"/>
+ <o o="0" r="brake" c="free" x="968" y="1849"/>
+ <o o="0" r="right" c="free" x="1338" y="1897"/>
+ <o o="0" r="right" c="free" x="973" y="1913"/>
+ <o o="0" r="right" c="free" x="479" y="3702"/>
+ <o o="0" r="left" c="free" x="1237" y="3801"/>
+ <o o="90" r="left" c="free" x="1295" y="3500"/>
+ <o o="90" r="left" c="free" x="1297" y="3382"/>
+ <o o="0" r="left" c="free" x="3030" y="4373"/>
+ <o o="0" r="brake" c="free" x="3290" y="1597"/>
+ <o o="180" r="dustRacing2DBanner" c="free" x="2729" y="2339"/>
+ <o o="180" r="dustRacing2DBanner" c="free" x="2463" y="2340"/>
+ <o o="180" r="dustRacing2DBanner" c="free" x="2193" y="2338"/>
+ <o o="180" r="grandstand" c="free" x="2204" y="2440"/>
+ <o o="180" r="grandstand" c="free" x="2366" y="2440"/>
+ <o o="180" r="grandstand" c="free" x="2527" y="2440"/>
+ <o o="180" r="grandstand" c="free" x="2680" y="2439"/>
+ <o o="0" r="rock" c="free" x="3112" y="1248"/>
+ <o o="0" r="rock" c="free" x="3076" y="1435"/>
+ <o o="0" r="rock" c="free" x="3008" y="1546"/>
+ <o o="0" r="rock" c="free" x="3138" y="1245"/>
+ <o o="0" r="rock" c="free" x="2980" y="1131"/>
+ <o o="0" r="rock" c="free" x="3152" y="1080"/>
+ <o o="0" r="rock" c="free" x="3224" y="1059"/>
+ <o o="0" r="rock" c="free" x="3300" y="1014"/>
+ <o o="0" r="rock" c="free" x="3066" y="883"/>
+ <o o="0" r="rock" c="free" x="3011" y="1059"/>
+ <o o="0" r="rock" c="free" x="3211" y="1135"/>
+ <o o="0" r="rock" c="free" x="3242" y="1242"/>
+ <o o="0" r="rock" c="free" x="2976" y="1328"/>
+ <o o="0" r="rock" c="free" x="2997" y="1183"/>
+ <o o="0" r="rock" c="free" x="3121" y="1345"/>
+ <o o="0" r="rock" c="free" x="3176" y="1397"/>
+ <o o="0" r="rock" c="free" x="3352" y="1018"/>
+ <o o="0" r="rock" c="free" x="3121" y="887"/>
+ <o o="0" r="rock" c="free" x="3187" y="728"/>
+ <o o="0" r="rock" c="free" x="3328" y="752"/>
+ <o o="0" r="rock" c="free" x="2973" y="680"/>
+ <o o="0" r="rock" c="free" x="2918" y="442"/>
+ <o o="0" r="rock" c="free" x="2718" y="369"/>
+ <o o="0" r="rock" c="free" x="2938" y="421"/>
+ <o o="0" r="rock" c="free" x="2987" y="573"/>
+ <o o="0" r="rock" c="free" x="3093" y="593"/>
+ <o o="0" r="rock" c="free" x="3307" y="593"/>
+ <o o="0" r="rock" c="free" x="3204" y="883"/>
+ <o o="0" r="rock" c="free" x="2980" y="849"/>
+ <o o="0" r="rock" c="free" x="3021" y="966"/>
+ <o o="0" r="rock" c="free" x="3211" y="969"/>
+ <o o="0" r="rock" c="free" x="2952" y="1231"/>
+ <o o="0" r="rock" c="free" x="3100" y="1124"/>
+ <o o="0" r="rock" c="free" x="3187" y="1497"/>
+ <o o="0" r="rock" c="free" x="3921" y="2400"/>
+ <o o="0" r="rock" c="free" x="4404" y="2197"/>
+ <o o="0" r="rock" c="free" x="4511" y="2338"/>
+ <o o="0" r="rock" c="free" x="4659" y="2235"/>
+ <o o="0" r="rock" c="free" x="4652" y="2366"/>
+ <o o="0" r="rock" c="free" x="4290" y="2438"/>
+ <o o="0" r="rock" c="free" x="4035" y="2218"/>
+ <o o="0" r="rock" c="free" x="3811" y="2235"/>
+ <o o="0" r="rock" c="free" x="4014" y="2335"/>
+ <o o="0" r="rock" c="free" x="3845" y="2604"/>
+ <o o="0" r="rock" c="free" x="3869" y="2724"/>
+ <o o="0" r="rock" c="free" x="3776" y="2773"/>
+ <o o="0" r="rock" c="free" x="3949" y="2924"/>
+ <o o="0" r="rock" c="free" x="3842" y="3004"/>
+ <o o="0" r="rock" c="free" x="3883" y="3131"/>
+ <o o="0" r="rock" c="free" x="2967" y="1881"/>
+ <o o="0" r="rock" c="free" x="3138" y="1887"/>
+ <o o="0" r="rock" c="free" x="3045" y="2011"/>
+ <o o="0" r="rock" c="free" x="3073" y="2156"/>
+ <o o="0" r="rock" c="free" x="2945" y="1652"/>
+ <o o="0" r="rock" c="free" x="2338" y="949"/>
+ <o o="0" r="rock" c="free" x="2242" y="921"/>
+ <o o="0" r="rock" c="free" x="2476" y="918"/>
+ <o o="0" r="rock" c="free" x="2428" y="883"/>
+ <o o="0" r="rock" c="free" x="1418" y="1004"/>
+ <o o="0" r="rock" c="free" x="1311" y="1124"/>
+ <o o="0" r="rock" c="free" x="1611" y="838"/>
+ <o o="0" r="wallLong" c="free" x="1093" y="1030"/>
+ <o o="0" r="wallLong" c="free" x="1357" y="1028"/>
+ <o o="90" r="wallLong" c="free" x="2156" y="998"/>
+ <o o="90" r="wallLong" c="free" x="2158" y="1276"/>
+ <o o="90" r="wallLong" c="free" x="2183" y="3880"/>
+ <o o="90" r="wallLong" c="free" x="2184" y="4417"/>
+ <o o="90" r="wallLong" c="free" x="2183" y="4688"/>
+ <o o="90" r="wallLong" c="free" x="2996" y="4702"/>
+ <o o="0" r="rock" c="free" x="4498" y="2921"/>
+ <o o="0" r="rock" c="free" x="4692" y="2925"/>
+ <o o="0" r="rock" c="free" x="4588" y="2907"/>
+ <o o="0" r="rock" c="free" x="4772" y="2945"/>
+ <o o="0" r="rock" c="free" x="4925" y="3068"/>
+ <o o="0" r="rock" c="free" x="4587" y="3130"/>
+ <o o="0" r="rock" c="free" x="4453" y="2927"/>
+ <o o="0" r="rock" c="free" x="4486" y="2978"/>
+ <o o="0" r="rock" c="free" x="4515" y="3072"/>
+ <o o="0" r="rock" c="free" x="4596" y="3017"/>
+ <o o="0" r="rock" c="free" x="4458" y="3035"/>
+ <o o="0" r="rock" c="free" x="4439" y="2956"/>
+ <o o="0" r="rock" c="free" x="4443" y="3100"/>
+ <o o="0" r="rock" c="free" x="4462" y="3160"/>
+ <o o="0" r="rock" c="free" x="4566" y="2958"/>
+ <o o="0" r="rock" c="free" x="4529" y="2982"/>
+ <o o="0" r="rock" c="free" x="4653" y="2972"/>
+ <o o="0" r="rock" c="free" x="4690" y="3027"/>
+ <o o="0" r="rock" c="free" x="4945" y="2998"/>
+ <o o="0" r="rock" c="free" x="4798" y="3031"/>
+ <o o="0" r="crate" c="free" x="1394" y="4047"/>
+ <o o="0" r="crate" c="free" x="1570" y="4156"/>
+ <o o="0" r="crate" c="free" x="1398" y="4262"/>
+ <o o="0" r="crate" c="free" x="1474" y="4276"/>
+ <o o="0" r="crate" c="free" x="1590" y="4294"/>
+ <o o="0" r="crate" c="free" x="1702" y="4292"/>
+ <o o="0" r="crate" c="free" x="1543" y="4235"/>
+ <o o="0" r="crate" c="free" x="1464" y="4209"/>
+ <o o="0" r="crate" c="free" x="1396" y="4182"/>
+ <o o="0" r="crate" c="free" x="1396" y="4147"/>
+ <o o="0" r="crate" c="free" x="1464" y="4078"/>
+ <o o="0" r="crate" c="free" x="1496" y="4143"/>
+ <o o="0" r="crate" c="free" x="1686" y="4225"/>
+ <o o="0" r="crate" c="free" x="1623" y="4174"/>
+ <o o="0" r="crate" c="free" x="1429" y="3943"/>
+ <o o="154" r="crate" c="free" x="1872" y="4584"/>
+ <o o="11" r="crate" c="free" x="1913" y="4682"/>
+ <o o="78" r="crate" c="free" x="2137" y="4774"/>
+ <o o="129" r="crate" c="free" x="2121" y="4682"/>
+ <o o="263" r="crate" c="free" x="2031" y="4700"/>
+ <o o="131" r="crate" c="free" x="2058" y="4578"/>
+ <o o="212" r="crate" c="free" x="1306" y="4789"/>
+ <o o="318" r="crate" c="free" x="1298" y="4892"/>
+ <o o="108" r="crate" c="free" x="1211" y="4753"/>
+ <o o="346" r="crate" c="free" x="1366" y="4851"/>
+ <o o="224" r="crate" c="free" x="1852" y="4519"/>
+ <o o="229" r="crate" c="free" x="1249" y="4830"/>
+ <o o="113" r="crate" c="free" x="1390" y="4804"/>
+ <o o="271" r="crate" c="free" x="1077" y="4793"/>
+ <o o="229" r="crate" c="free" x="1358" y="4944"/>
+ <o o="68" r="crate" c="free" x="1629" y="4251"/>
+ <o o="242" r="crate" c="free" x="1613" y="4062"/>
+ <o o="136" r="crate" c="free" x="1933" y="4515"/>
+ <o o="261" r="crate" c="free" x="1988" y="4713"/>
+ <o o="94" r="rock" c="free" x="997" y="4866"/>
+ <o o="80" r="rock" c="free" x="2721" y="4280"/>
+ <o o="70" r="rock" c="free" x="2859" y="4324"/>
+ <o o="91" r="rock" c="free" x="2683" y="4680"/>
+ <o o="190" r="rock" c="free" x="2814" y="4476"/>
+ <o o="276" r="rock" c="free" x="2859" y="4514"/>
+ <o o="168" r="rock" c="free" x="3137" y="5062"/>
+ <o o="194" r="rock" c="free" x="4211" y="4983"/>
+ <o o="209" r="rock" c="free" x="3578" y="5073"/>
+ <o o="322" r="rock" c="free" x="3314" y="5456"/>
+ <o o="77" r="rock" c="free" x="2666" y="4824"/>
+ <o o="159" r="rock" c="free" x="2042" y="3638"/>
+ <o o="323" r="rock" c="free" x="1983" y="4073"/>
+ <o o="340" r="rock" c="free" x="1663" y="3670"/>
+ <o o="291" r="rock" c="free" x="2456" y="3242"/>
+ <o o="47" r="rock" c="free" x="3059" y="3383"/>
+ <o o="170" r="rock" c="free" x="2849" y="3559"/>
+ <o o="271" r="rock" c="free" x="3440" y="3639"/>
+ <o o="33" r="rock" c="free" x="3762" y="3469"/>
+ <o o="267" r="rock" c="free" x="2562" y="3318"/>
+ <o o="140" r="rock" c="free" x="2962" y="3231"/>
+ <o o="146" r="rock" c="free" x="2273" y="2649"/>
+ <o o="178" r="rock" c="free" x="2614" y="2693"/>
+ <o o="241" r="rock" c="free" x="3014" y="2400"/>
+ <o o="87" r="rock" c="free" x="1721" y="1759"/>
+ <o o="292" r="rock" c="free" x="1524" y="2031"/>
+ <o o="18" r="rock" c="free" x="1480" y="2328"/>
+ <o o="348" r="rock" c="free" x="1583" y="2704"/>
+ <o o="54" r="rock" c="free" x="2335" y="1631"/>
+ <o o="48" r="rock" c="free" x="1566" y="3228"/>
+ <o o="311" r="rock" c="free" x="604" y="2783"/>
+ <o o="149" r="rock" c="free" x="766" y="2345"/>
+ <o o="129" r="rock" c="free" x="721" y="1393"/>
+ <o o="21" r="rock" c="free" x="3507" y="1145"/>
+ <o o="240" r="rock" c="free" x="3442" y="897"/>
+ <o o="319" r="rock" c="free" x="3500" y="724"/>
+ <o o="169" r="rock" c="free" x="3273" y="383"/>
+ <o o="48" r="rock" c="free" x="3597" y="466"/>
+ <o o="25" r="rock" c="free" x="4269" y="2300"/>
+ <o o="250" r="rock" c="free" x="4642" y="3087"/>
+ <o o="242" r="rock" c="free" x="5076" y="2987"/>
+ <o o="103" r="rock" c="free" x="5512" y="2897"/>
+ <o o="281" r="rock" c="free" x="5107" y="2900"/>
+ <o o="205" r="rock" c="free" x="5004" y="3121"/>
+ <o o="0" r="tire" c="free" x="4607" y="4133"/>
+ <o o="0" r="tire" c="free" x="4635" y="4133"/>
+ <o o="0" r="tire" c="free" x="4674" y="4123"/>
+ <o o="0" r="tire" c="free" x="4698" y="4113"/>
+ <o o="0" r="tire" c="free" x="4730" y="4106"/>
+ <o o="0" r="tire" c="free" x="4774" y="4093"/>
+ <o o="0" r="tire" c="free" x="4797" y="4079"/>
+ <o o="0" r="tire" c="free" x="4811" y="4065"/>
+ <o o="0" r="tire" c="free" x="4826" y="4043"/>
+ <o o="0" r="tire" c="free" x="4841" y="4018"/>
+ <o o="0" r="tire" c="free" x="4848" y="3991"/>
+ <o o="0" r="tire" c="free" x="4854" y="3940"/>
+ <o o="0" r="tire" c="free" x="4863" y="3910"/>
+ <o o="0" r="tire" c="free" x="4600" y="4167"/>
+ <o o="0" r="tire" c="free" x="4639" y="4167"/>
+ <o o="0" r="tire" c="free" x="4694" y="4157"/>
+ <o o="0" r="tire" c="free" x="4735" y="4146"/>
+ <o o="0" r="tire" c="free" x="4785" y="4131"/>
+ <o o="0" r="tire" c="free" x="4841" y="4093"/>
+ <o o="0" r="tire" c="free" x="4874" y="4059"/>
+ <o o="0" r="tire" c="free" x="4885" y="4010"/>
+ <o o="0" r="tire" c="free" x="4898" y="3952"/>
+ <o o="0" r="tire" c="free" x="4705" y="3292"/>
+ <o o="0" r="tire" c="free" x="4781" y="3320"/>
+ <o o="0" r="tire" c="free" x="4810" y="3345"/>
+ <o o="0" r="tire" c="free" x="4898" y="3415"/>
+ <o o="0" r="tire" c="free" x="4904" y="3449"/>
+ <o o="0" r="tire" c="free" x="4909" y="3526"/>
+ <o o="0" r="tire" c="free" x="4850" y="3388"/>
+ <o o="0" r="tire" c="free" x="4865" y="3440"/>
+ <o o="0" r="tire" c="free" x="4831" y="3349"/>
+ <o o="0" r="tire" c="free" x="4776" y="3285"/>
+ <o o="0" r="tire" c="free" x="4820" y="3304"/>
+ <o o="0" r="tire" c="free" x="4846" y="3339"/>
+ <o o="0" r="tire" c="free" x="4874" y="3361"/>
+ <o o="0" r="tire" c="free" x="4902" y="3394"/>
+ <o o="0" r="tire" c="free" x="4891" y="3484"/>
+ <o o="0" r="tire" c="free" x="4926" y="3546"/>
+ <o o="0" r="tire" c="free" x="4906" y="3572"/>
+ <o o="0" r="tire" c="free" x="4961" y="3452"/>
+ <o o="0" r="tire" c="free" x="4933" y="3480"/>
+ <o o="0" r="tire" c="free" x="478" y="3853"/>
+ <o o="0" r="tire" c="free" x="480" y="3913"/>
+ <o o="0" r="tire" c="free" x="479" y="3941"/>
+ <o o="0" r="tire" c="free" x="483" y="3966"/>
+ <o o="0" r="tire" c="free" x="476" y="4026"/>
+ <o o="0" r="tire" c="free" x="481" y="4067"/>
+ <o o="0" r="tire" c="free" x="453" y="4087"/>
+ <o o="0" r="tire" c="free" x="453" y="4050"/>
+ <o o="0" r="tire" c="free" x="448" y="4006"/>
+ <o o="0" r="tire" c="free" x="448" y="3913"/>
+ <o o="0" r="tire" c="free" x="450" y="3853"/>
+ <o o="0" r="tire" c="free" x="433" y="3949"/>
+ <o o="0" r="tire" c="free" x="411" y="3979"/>
+ <o o="0" r="tire" c="free" x="448" y="3965"/>
+ <o o="0" r="tire" c="free" x="420" y="4011"/>
+ <o o="0" r="tire" c="free" x="467" y="3992"/>
+ <o o="0" r="tire" c="free" x="475" y="3881"/>
+ <o o="0" r="tire" c="free" x="468" y="3811"/>
+ <o o="0" r="tire" c="free" x="484" y="3336"/>
+ <o o="0" r="tire" c="free" x="476" y="3394"/>
+ <o o="0" r="tire" c="free" x="467" y="3450"/>
+ <o o="0" r="tire" c="free" x="467" y="3544"/>
+ <o o="0" r="tire" c="free" x="463" y="3602"/>
+ <o o="0" r="tire" c="free" x="463" y="3654"/>
+ <o o="0" r="tire" c="free" x="431" y="3668"/>
+ <o o="0" r="tire" c="free" x="423" y="3705"/>
+ <o o="0" r="tire" c="free" x="444" y="3771"/>
+ <o o="0" r="tire" c="free" x="406" y="3839"/>
+ <o o="0" r="tire" c="free" x="413" y="3875"/>
+ <o o="0" r="tire" c="free" x="2652" y="468"/>
+ <o o="0" r="tire" c="free" x="2693" y="474"/>
+ <o o="0" r="tire" c="free" x="2743" y="500"/>
+ <o o="0" r="tire" c="free" x="2778" y="554"/>
+ <o o="0" r="tire" c="free" x="2801" y="604"/>
+ <o o="0" r="tire" c="free" x="2765" y="533"/>
+ <o o="0" r="tire" c="free" x="2715" y="494"/>
+ <o o="0" r="tire" c="free" x="1789" y="678"/>
+ <o o="0" r="tire" c="free" x="1798" y="630"/>
+ <o o="0" r="tire" c="free" x="1815" y="584"/>
+ <o o="0" r="tire" c="free" x="1831" y="553"/>
+ <o o="0" r="tire" c="free" x="1858" y="532"/>
+ <o o="0" r="tire" c="free" x="1893" y="510"/>
+ <o o="0" r="tire" c="free" x="1935" y="493"/>
+ <o o="0" r="tire" c="free" x="1981" y="483"/>
+ <o o="0" r="grandstand" c="free" x="2431" y="3706"/>
+ <o o="0" r="grandstand" c="free" x="2639" y="3706"/>
+ <o o="0" r="grandstand" c="free" x="2846" y="3704"/>
+ <o o="0" r="grandstand" c="free" x="3081" y="3702"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="2413" y="3802"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="2680" y="3804"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="2944" y="3805"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="3209" y="3805"/>
+ <o o="0" r="tire" c="free" x="3233" y="3859"/>
+ <o o="0" r="tire" c="free" x="3267" y="3880"/>
+ <o o="0" r="tire" c="free" x="3288" y="3906"/>
+ <o o="0" r="tire" c="free" x="3313" y="3932"/>
+ <o o="0" r="tire" c="free" x="3322" y="3967"/>
+ <o o="0" r="tire" c="free" x="3328" y="4001"/>
+ <o o="0" r="tire" c="free" x="3271" y="3843"/>
+ <o o="0" r="tire" c="free" x="3302" y="3867"/>
+ <o o="0" r="tire" c="free" x="3327" y="3889"/>
+ <o o="0" r="tire" c="free" x="3357" y="3940"/>
+ <o o="0" r="tire" c="free" x="3357" y="3978"/>
+ <o o="0" r="tire" c="free" x="3352" y="4039"/>
+ <o o="0" r="tire" c="free" x="3374" y="4015"/>
+ <o o="0" r="tire" c="free" x="1202" y="3853"/>
+ <o o="0" r="tire" c="free" x="1226" y="3868"/>
+ <o o="0" r="tire" c="free" x="1243" y="3885"/>
+ <o o="0" r="tire" c="free" x="1254" y="3924"/>
+ <o o="0" r="tire" c="free" x="1254" y="3852"/>
+ <o o="0" r="tire" c="free" x="1262" y="3865"/>
+ <o o="0" r="tire" c="free" x="1270" y="3888"/>
+ <o o="0" r="tire" c="free" x="1289" y="3918"/>
+ <o o="0" r="tire" c="free" x="1285" y="3861"/>
+ <o o="0" r="tire" c="free" x="1266" y="3946"/>
+ <o o="90" r="wallLong" c="free" x="3041" y="610"/>
+ <o o="90" r="wallLong" c="free" x="3042" y="877"/>
+ <o o="90" r="wallLong" c="free" x="3043" y="1142"/>
+ <o o="0" r="wallLong" c="free" x="2387" y="2014"/>
+ <o o="90" r="wallLong" c="free" x="2527" y="1874"/>
+ <o o="90" r="wallLong" c="free" x="3279" y="2335"/>
+ <o o="90" r="wallLong" c="free" x="3278" y="2068"/>
+ <o o="90" r="wall" c="free" x="3279" y="2768"/>
+ <o o="90" r="wallLong" c="free" x="3279" y="2599"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="3128" y="2790"/>
+ <o o="90" r="left" c="free" x="2967" y="3111"/>
+ <o o="0" r="wall" c="free" x="4542" y="3592"/>
+ <o o="90" r="wall" c="free" x="4589" y="3783"/>
+ <o o="90" r="wall" c="free" x="4588" y="3639"/>
+ <o o="0" r="wall" c="free" x="4544" y="3830"/>
+ <o o="90" r="wall" c="free" x="4588" y="3714"/>
+ <o o="0" r="wall" c="free" x="3937" y="4144"/>
+ <o o="0" r="wall" c="free" x="4016" y="4143"/>
+ <o o="0" r="wall" c="free" x="4089" y="4144"/>
+ <o o="90" r="wall" c="free" x="3883" y="4187"/>
+ <o o="90" r="wall" c="free" x="3885" y="4264"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="3453" y="4599"/>
+ <o o="0" r="crate" c="free" x="3053" y="4211"/>
+ <o o="0" r="crate" c="free" x="3008" y="4189"/>
+ <o o="298" r="crate" c="free" x="2929" y="4158"/>
+ <o o="120" r="crate" c="free" x="2987" y="4130"/>
+ <o o="121" r="crate" c="free" x="3039" y="4157"/>
+ <o o="151" r="crate" c="free" x="2966" y="4207"/>
+ <o o="299" r="crate" c="free" x="2866" y="4144"/>
+ <o o="196" r="crate" c="free" x="2938" y="4116"/>
+ <o o="180" r="crate" c="free" x="2878" y="4179"/>
+ <o o="137" r="crate" c="free" x="2975" y="4300"/>
+ <o o="54" r="crate" c="free" x="2924" y="4233"/>
+ <o o="9" r="crate" c="free" x="3024" y="4281"/>
+ <o o="55" r="crate" c="free" x="2959" y="4350"/>
+ <o o="52" r="crate" c="free" x="2982" y="4258"/>
+ <o o="242" r="crate" c="free" x="2896" y="4303"/>
+ <o o="329" r="crate" c="free" x="2793" y="4145"/>
+ <o o="171" r="crate" c="free" x="2826" y="4204"/>
+ <o o="194" r="crate" c="free" x="2662" y="4180"/>
+ <o o="292" r="crate" c="free" x="2626" y="4242"/>
+ <o o="60" r="crate" c="free" x="2622" y="4168"/>
+ <o o="89" r="crate" c="free" x="2700" y="4138"/>
+ <o o="11" r="crate" c="free" x="2752" y="4183"/>
+ <o o="356" r="crate" c="free" x="2696" y="4200"/>
+ <o o="322" r="crate" c="free" x="2654" y="4281"/>
+ <o o="23" r="crate" c="free" x="2631" y="4350"/>
+ <o o="53" r="crate" c="free" x="2754" y="4229"/>
+ <o o="63" r="crate" c="free" x="2843" y="4260"/>
+ <o o="32" r="crate" c="free" x="1883" y="4690"/>
+ <o o="86" r="crate" c="free" x="1861" y="4746"/>
+ <o o="228" r="crate" c="free" x="1943" y="4749"/>
+ <o o="167" r="crate" c="free" x="1966" y="4816"/>
+ <o o="333" r="crate" c="free" x="1896" y="4780"/>
+ <o o="308" r="crate" c="free" x="2067" y="4794"/>
+ <o o="338" r="crate" c="free" x="1836" y="4612"/>
+ <o o="0" r="wallLong" c="free" x="4482" y="3237"/>
+ <o o="0" r="wallLong" c="free" x="4746" y="3236"/>
+ <o o="0" r="wallLong" c="free" x="5007" y="3233"/>
+ <o o="-40" r="wallLong" c="free" x="5505" y="3148"/>
+ <o o="0" r="rock" c="free" x="4409" y="2888"/>
+ <o o="0" r="rock" c="free" x="4468" y="2869"/>
+ <o o="0" r="rock" c="free" x="4426" y="2990"/>
+ <o o="0" r="rock" c="free" x="4534" y="2882"/>
+ <o o="0" r="rock" c="free" x="4591" y="2877"/>
+ <o o="0" r="rock" c="free" x="4857" y="2896"/>
+ <o o="0" r="rock" c="free" x="4657" y="3174"/>
+ <o o="90" r="wallLong" c="free" x="2184" y="4147"/>
+ <o o="0" r="wallLong" c="free" x="1460" y="3833"/>
+ <o o="0" r="wallLong" c="free" x="1734" y="3837"/>
+ <o o="0" r="wallLong" c="free" x="613" y="4128"/>
+ <o o="0" r="wallLong" c="free" x="874" y="4128"/>
+ <o o="180" r="wallLong" c="free" x="1286" y="4691"/>
+ <o o="90" r="wallLong" c="free" x="1428" y="4818"/>
+ <o o="0" r="wallLong" c="free" x="1460" y="3597"/>
+ <o o="0" r="wallLong" c="free" x="2009" y="3839"/>
+ <o o="0" r="wallLong" c="free" x="1616" y="1027"/>
+ <o o="90" r="wallLong" c="free" x="1758" y="1150"/>
+ <o o="90" r="wallLong" c="free" x="1756" y="882"/>
+ <o o="0" r="dustRacing2DBanner" c="free" x="2203" y="811"/>
+ <o o="90" r="wallLong" c="free" x="2521" y="926"/>
+ <o o="90" r="wallLong" c="free" x="3041" y="1409"/>
+ <o o="90" r="wallLong" c="free" x="3042" y="1671"/>
+ <o o="0" r="brake" c="free" x="2845" y="1720"/>
+ <o o="0" r="left" c="free" x="2520" y="1666"/>
+ <o o="0" r="brake" c="free" x="2520" y="1718"/>
+ <o o="0" r="left" c="free" x="2271" y="4628"/>
+ <o o="0" r="left" c="free" x="2600" y="4626"/>
+ <o o="45" r="left" c="free" x="1849" y="4803"/>
+ <o o="45" r="left" c="free" x="1826" y="5176"/>
+ <o o="90" r="wallLong" c="free" x="501" y="4283"/>
+ <o o="90" r="wallLong" c="free" x="504" y="4544"/>
+ <o o="0" r="wallLong" c="free" x="761" y="4688"/>
+ <o o="0" r="wallLong" c="free" x="1021" y="4690"/>
+ <o o="0" r="wall" c="free" x="594" y="4688"/>
+ <o o="0" r="wall" c="free" x="523" y="4686"/>
+ <o o="0" r="wallLong" c="free" x="1843" y="4194"/>
+ <o o="0" r="left" c="free" x="5178" y="2183"/>
+ <o o="0" r="wallLong" c="free" x="5267" y="3229"/>
+ <o o="0" r="rock" c="free" x="2763" y="257"/>
+ <o o="0" r="rock" c="free" x="3278" y="221"/>
+ <o o="0" r="rock" c="free" x="3426" y="484"/>
+ <o o="289" r="rock" c="free" x="563" y="1863"/>
+ <o o="146" r="rock" c="free" x="321" y="2605"/>
+ <o o="156" r="rock" c="free" x="352" y="1000"/>
+ <o o="213" r="rock" c="free" x="2089" y="3384"/>
+ <o o="359" r="rock" c="free" x="4252" y="4605"/>
+ <o o="275" r="rock" c="free" x="4794" y="4326"/>
+ <o o="331" r="rock" c="free" x="5078" y="3515"/>
+ <o o="245" r="rock" c="free" x="4052" y="4357"/>
+ <n h="256" i="0" x="1170" y="1681" w="256"/>
+ <n h="256" i="1" x="1284" y="1435" w="256"/>
+ <n h="256" i="2" x="1844" y="1349" w="300"/>
+ <n h="256" i="3" x="1962" y="749" w="400"/>
+ <n h="256" i="4" x="2178" y="656" w="256"/>
+ <n h="256" i="5" x="2532" y="648" w="256"/>
+ <n h="256" i="6" x="2679" y="805" w="400"/>
+ <n h="256" i="7" x="2656" y="1720" w="400"/>
+ <n h="400" i="8" x="2601" y="2072" w="256"/>
+ <n h="256" i="9" x="1988" y="2154" w="400"/>
+ <n h="256" i="10" x="1898" y="2754" w="400"/>
+ <n h="400" i="11" x="2040" y="2908" w="256"/>
+ <n h="400" i="12" x="2948" y="2914" w="256"/>
+ <n h="256" i="13" x="3376" y="2829" w="400"/>
+ <n h="256" i="14" x="3403" y="2073" w="400"/>
+ <n h="256" i="15" x="3527" y="1454" w="256"/>
+ <n h="256" i="16" x="3887" y="1441" w="256"/>
+ <n h="366" i="17" x="4054" y="1871" w="256"/>
+ <n h="256" i="18" x="4405" y="1876" w="400"/>
+ <n h="256" i="19" x="4552" y="1448" w="256"/>
+ <n h="256" i="20" x="4948" y="1476" w="400"/>
+ <n h="256" i="21" x="5009" y="2160" w="300"/>
+ <n h="400" i="22" x="4886" y="2616" w="256"/>
+ <n h="256" i="23" x="4234" y="2806" w="256"/>
+ <n h="256" i="24" x="4214" y="3282" w="256"/>
+ <n h="256" i="25" x="4505" y="3446" w="256"/>
+ <n h="256" i="26" x="4752" y="3690" w="256"/>
+ <n h="333" i="27" x="4534" y="4021" w="256"/>
+ <n h="256" i="28" x="3738" y="4045" w="300"/>
+ <n h="400" i="29" x="3642" y="4706" w="256"/>
+ <n h="256" i="30" x="3250" y="4650" w="400"/>
+ <n h="256" i="31" x="3133" y="4056" w="400"/>
+ <n h="256" i="32" x="2530" y="4013" w="256"/>
+ <n h="256" i="33" x="2390" y="4421" w="340"/>
+ <n h="400" i="34" x="2316" y="4925" w="256"/>
+ <n h="256" i="35" x="1786" y="4905" w="500"/>
+ <n h="456" i="36" x="1581" y="4544" w="300"/>
+ <n h="256" i="37" x="1198" y="4373" w="300"/>
+ <n h="256" i="38" x="1100" y="4025" w="400"/>
+ <n h="256" i="39" x="667" y="3900" w="256"/>
+ <n h="256" i="40" x="707" y="3532" w="400"/>
+ <n h="256" i="41" x="1082" y="3379" w="400"/>
+ <n h="256" i="42" x="1152" y="2429" w="256"/>
+ <n h="256" i="43" x="1151" y="2068" w="256"/>
+ <n h="256" i="44" x="1170" y="1681" w="256"/>
</track>
diff -Nuar a/README.md b/README.md
--- a/README.md 2017-12-30 16:09:21.000000000 +0300
+++ b/README.md 2018-02-11 08:22:08.000000000 +0300
@@ -11,7 +11,7 @@
</tr>
</table>
-<a href="https://www.youtube.com/watch?feature=player_embedded&v=_0f7rpGYE5g">Video of the game</a>
+<a href="https://www.youtube.com/watch?feature=player_embedded&v=3hrIzzItggQ">Video of the game</a>
Dust Racing (Dustrac) is a tile-based, cross-platform 2D racing game written
in Qt (C++) and OpenGL.
diff -Nuar a/src/editor/application.cpp b/src/editor/application.cpp
--- a/src/editor/application.cpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/application.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -58,7 +58,7 @@
QString lang = "";
const std::vector<QString> args(argv, argv + argc);
- for (unsigned int i = 0; i < args.size(); i++)
+ for (unsigned int i = 1; i < args.size(); i++)
{
if (args[i] == "-h" || args[i] == "--help")
{
diff -Nuar a/src/editor/CMakeLists.txt b/src/editor/CMakeLists.txt
--- a/src/editor/CMakeLists.txt 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/CMakeLists.txt 2018-02-11 08:22:08.000000000 +0300
@@ -10,12 +10,15 @@
set(SRC
aboutdlg.cpp
application.cpp
+ draganddropstore.cpp
editordata.cpp
editorview.cpp
- editorscene.cpp
+ editormode.hpp
+ floodfill.cpp
main.cpp
mainwindow.cpp
map.cpp
+ mediator.cpp
newtrackdialog.cpp
object.cpp
objectfactory.cpp
diff -Nuar a/src/editor/draganddropstore.cpp b/src/editor/draganddropstore.cpp
--- a/src/editor/draganddropstore.cpp 1970-01-01 02:00:00.000000000 +0200
+++ b/src/editor/draganddropstore.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -0,0 +1,69 @@
+// This file is part of Dust Racing 2D.
+// Copyright (C) 2018 Jussi Lind <jussi.lind@iki.fi>
+//
+// Dust Racing 2D is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Dust Racing 2D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
+
+#include "draganddropstore.hpp"
+
+DragAndDropStore::DragAndDropStore()
+{
+}
+
+void DragAndDropStore::clear()
+{
+ m_dragAndDropSourceTile = nullptr;
+
+ m_dragAndDropObject = nullptr;
+
+ m_dragAndDropTargetNode = nullptr;
+}
+
+void DragAndDropStore::setDragAndDropSourceTile(TrackTile * tile)
+{
+ m_dragAndDropSourceTile = tile;
+}
+
+TrackTile * DragAndDropStore::dragAndDropSourceTile() const
+{
+ return m_dragAndDropSourceTile;
+}
+
+void DragAndDropStore::setDragAndDropObject(Object * object)
+{
+ m_dragAndDropObject = object;
+}
+
+Object * DragAndDropStore::dragAndDropObject() const
+{
+ return m_dragAndDropObject;
+}
+
+void DragAndDropStore::setDragAndDropTargetNode(TargetNode * tnode)
+{
+ m_dragAndDropTargetNode = tnode;
+}
+
+TargetNode * DragAndDropStore::dragAndDropTargetNode() const
+{
+ return m_dragAndDropTargetNode;
+}
+
+void DragAndDropStore::setDragAndDropSourcePos(QPointF pos)
+{
+ m_dragAndDropSourcePos = pos;
+}
+
+QPointF DragAndDropStore::dragAndDropSourcePos() const
+{
+ return m_dragAndDropSourcePos;
+}
diff -Nuar a/src/editor/draganddropstore.hpp b/src/editor/draganddropstore.hpp
--- a/src/editor/draganddropstore.hpp 1970-01-01 02:00:00.000000000 +0200
+++ b/src/editor/draganddropstore.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -0,0 +1,60 @@
+// This file is part of Dust Racing 2D.
+// Copyright (C) 2018 Jussi Lind <jussi.lind@iki.fi>
+//
+// Dust Racing 2D is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Dust Racing 2D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef DRAGANDDROPSTORE_HPP
+#define DRAGANDDROPSTORE_HPP
+
+#include <QPointF>
+
+class Object;
+class TargetNode;
+class TrackTile;
+
+class DragAndDropStore
+{
+public:
+
+ DragAndDropStore();
+
+ void clear();
+
+ void setDragAndDropTargetNode(TargetNode * tnode);
+
+ TargetNode * dragAndDropTargetNode() const;
+
+ QPointF dragAndDropSourcePos() const;
+
+ void setDragAndDropSourcePos(QPointF pos);
+
+ void setDragAndDropSourceTile(TrackTile * tile);
+
+ TrackTile * dragAndDropSourceTile() const;
+
+ void setDragAndDropObject(Object * object);
+
+ Object * dragAndDropObject() const;
+
+private:
+
+ TrackTile * m_dragAndDropSourceTile = nullptr;
+
+ Object * m_dragAndDropObject = nullptr;
+
+ TargetNode * m_dragAndDropTargetNode = nullptr;
+
+ QPointF m_dragAndDropSourcePos;
+};
+
+#endif // DRAGANDDROPSTORE_HPP
diff -Nuar a/src/editor/editordata.cpp b/src/editor/editordata.cpp
--- a/src/editor/editordata.cpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/editordata.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -14,9 +14,9 @@
// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
#include "editordata.hpp"
-#include "editorscene.hpp"
#include "editorview.hpp"
#include "mainwindow.hpp"
+#include "mediator.hpp"
#include "object.hpp"
#include "objectmodelloader.hpp"
#include "targetnode.hpp"
@@ -28,10 +28,8 @@
using std::dynamic_pointer_cast;
-EditorData::EditorData(MainWindow * mainWindow)
-: m_mode(EditorMode::None)
-, m_dragAndDropSourcePos()
-, m_mainWindow(mainWindow)
+EditorData::EditorData(Mediator & mediator)
+ : m_mediator(mediator)
{}
void EditorData::clearScene()
@@ -41,6 +39,11 @@
removeTargetNodesFromScene();
}
+DragAndDropStore & EditorData::dadStore()
+{
+ return m_dadStore;
+}
+
bool EditorData::loadTrackData(QString fileName)
{
m_undoStack.clear();
@@ -60,16 +63,12 @@
{
if (m_undoStack.isUndoable())
{
- m_dragAndDropSourceTile = nullptr;
-
- m_dragAndDropObject = nullptr;
+ m_dadStore.clear();
m_selectedObject = nullptr;
m_selectedTargetNode = nullptr;
- m_dragAndDropTargetNode = nullptr;
-
saveRedoPoint();
clearScene();
@@ -87,16 +86,12 @@
{
if (m_undoStack.isRedoable())
{
- m_dragAndDropSourceTile = nullptr;
-
- m_dragAndDropObject = nullptr;
+ m_dadStore.clear();
m_selectedObject = nullptr;
m_selectedTargetNode = nullptr;
- m_dragAndDropTargetNode = nullptr;
-
saveUndoPoint();
clearScene();
@@ -116,7 +111,7 @@
assert(m_trackData);
m_undoStack.pushUndoPoint(m_trackData);
- m_mainWindow->enableUndo(m_undoStack.isUndoable());
+ m_mediator.enableUndo(m_undoStack.isUndoable());
}
void EditorData::saveRedoPoint()
@@ -151,17 +146,11 @@
void EditorData::beginSetRoute()
{
assert(m_trackData);
- setMode(EditorMode::SetRoute);
+ m_mediator.setMode(EditorMode::SetRoute);
removeRouteFromScene();
m_trackData->route().clear();
}
-void EditorData::endSetRoute()
-{
- // Reset the editing mode.
- setMode(EditorMode::None);
-}
-
void EditorData::addExistingRouteToScene()
{
// Re-push existing (loaded) target nodes so that route lines
@@ -204,8 +193,8 @@
auto routeLine = new QGraphicsLineItem;
node->setRouteLine(routeLine);
- m_mainWindow->editorScene().addItem(node.get()); // The scene wants a raw pointer
- m_mainWindow->editorScene().addItem(routeLine);
+ m_mediator.addItem(node.get()); // The scene wants a raw pointer
+ m_mediator.addItem(routeLine);
const int routeLineZ = 10;
node->setZValue(routeLineZ);
@@ -214,8 +203,7 @@
// Check if we might have a loop => end
if (loopClosed)
{
- setMode(EditorMode::None);
- m_mainWindow->endSetRoute();
+ m_mediator.endSetRoute();
auto firstNode = route.get(0);
route.get(route.numNodes() - 1)->setLocation(firstNode->location());
@@ -232,13 +220,13 @@
auto node = dynamic_pointer_cast<TargetNode>(tnode);
assert(node);
- m_mainWindow->editorScene().removeItem(node.get()); // The scene wants a raw pointer
- m_mainWindow->editorScene().removeItem(node->routeLine());
+ m_mediator.removeItem(node.get()); // The scene wants a raw pointer
+ m_mediator.removeItem(node->routeLine());
delete node->routeLine();
}
- m_mainWindow->editorView().update();
+ m_mediator.updateView();
}
TrackDataPtr EditorData::trackData()
@@ -246,36 +234,6 @@
return m_trackData;
}
-EditorData::EditorMode EditorData::mode() const
-{
- return m_mode;
-}
-
-void EditorData::setMode(EditorData::EditorMode newMode)
-{
- m_mode = newMode;
-}
-
-void EditorData::setDragAndDropSourceTile(TrackTile * tile)
-{
- m_dragAndDropSourceTile = tile;
-}
-
-TrackTile * EditorData::dragAndDropSourceTile() const
-{
- return m_dragAndDropSourceTile;
-}
-
-void EditorData::setDragAndDropObject(Object * object)
-{
- m_dragAndDropObject = object;
-}
-
-Object * EditorData::dragAndDropObject() const
-{
- return m_dragAndDropObject;
-}
-
void EditorData::setSelectedObject(Object * object)
{
m_selectedObject = object;
@@ -296,26 +254,6 @@
return m_selectedTargetNode;
}
-void EditorData::setDragAndDropTargetNode(TargetNode * tnode)
-{
- m_dragAndDropTargetNode = tnode;
-}
-
-TargetNode * EditorData::dragAndDropTargetNode() const
-{
- return m_dragAndDropTargetNode;
-}
-
-void EditorData::setDragAndDropSourcePos(QPointF pos)
-{
- m_dragAndDropSourcePos = pos;
-}
-
-QPointF EditorData::dragAndDropSourcePos() const
-{
- return m_dragAndDropSourcePos;
-}
-
void EditorData::addTilesToScene()
{
assert(m_trackData);
@@ -331,7 +269,7 @@
if (!tile->added())
{
- m_mainWindow->editorScene().addItem(tile.get()); // The scene wants a raw pointer
+ m_mediator.addItem(tile.get()); // The scene wants a raw pointer
tile->setAdded(true);
}
@@ -351,7 +289,7 @@
auto object = dynamic_pointer_cast<Object>(m_trackData->objects().object(i));
assert(object);
- m_mainWindow->editorScene().addItem(object.get()); // The scene wants a raw pointer
+ m_mediator.addItem(object.get()); // The scene wants a raw pointer
object->setZValue(10);
}
@@ -364,7 +302,7 @@
auto tile = dynamic_pointer_cast<TrackTile>(trackTile);
assert(tile);
- m_mainWindow->editorScene().removeItem(tile.get()); // The scene wants a raw pointer
+ m_mediator.removeItem(tile.get()); // The scene wants a raw pointer
}
void EditorData::removeTilesFromScene()
@@ -380,7 +318,7 @@
auto tile = dynamic_pointer_cast<TrackTile>(m_trackData->map().getTile(i, j));
assert(tile);
- m_mainWindow->editorScene().removeItem(tile.get()); // The scene wants a raw pointer
+ m_mediator.removeItem(tile.get()); // The scene wants a raw pointer
}
}
}
@@ -395,12 +333,13 @@
auto object = dynamic_pointer_cast<Object>(m_trackData->objects().object(i));
assert(object);
- m_mainWindow->editorScene().removeItem(object.get()); // The scene wants a raw pointer
+ m_mediator.removeItem(object.get()); // The scene wants a raw pointer
}
}
m_selectedObject = nullptr;
- m_dragAndDropObject = nullptr;
+
+ m_dadStore.clear();
}
void EditorData::removeTargetNodesFromScene()
@@ -412,11 +351,21 @@
auto node = dynamic_pointer_cast<TargetNode>(tnode);
assert(node);
- m_mainWindow->editorScene().removeItem(node.get()); // The scene wants a raw pointer
+ m_mediator.removeItem(node.get()); // The scene wants a raw pointer
}
}
}
+int EditorData::currentScale() const
+{
+ return m_currentScale;
+}
+
+void EditorData::setCurrentScale(int currentScale)
+{
+ m_currentScale = currentScale;
+}
+
void EditorData::clearRoute()
{
assert(m_trackData);
@@ -424,7 +373,7 @@
removeRouteFromScene();
m_trackData->route().clear();
- m_mainWindow->console(QString(QObject::tr("Route cleared.")));
+ m_mediator.console(QString(QObject::tr("Route cleared.")));
}
void EditorData::setActiveColumn(unsigned int column)
diff -Nuar a/src/editor/editordata.hpp b/src/editor/editordata.hpp
--- a/src/editor/editordata.hpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/editordata.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -22,11 +22,13 @@
#include <QString>
#include <QPointF>
+#include "draganddropstore.hpp"
+#include "editormode.hpp"
#include "trackdata.hpp"
#include "trackio.hpp"
#include "undostack.hpp"
-class MainWindow;
+class Mediator;
class Object;
class ObjectModelLoader;
class TargetNode;
@@ -40,19 +42,10 @@
{
public:
- //! Editing modes.
- enum class EditorMode
- {
- None,
- SetRoute,
- SetTileType,
- AddObject,
- EraseObject
- };
-
//! Constructor.
- //! \param mainWindow Pointer to the main window.
- EditorData(MainWindow * mainWindow);
+ explicit EditorData(Mediator & mediator);
+
+ DragAndDropStore & dadStore();
//! Load track from the given file.
bool loadTrackData(QString fileName);
@@ -89,10 +82,6 @@
//! setting the route.
void beginSetRoute();
- //! This should be called after user ends
- //! setting the route.
- void endSetRoute();
-
//! Adds current target node objects to the scene.
void addExistingRouteToScene();
@@ -108,24 +97,6 @@
//! Returns current track data object. Returns NULL if not set.
TrackDataPtr trackData();
- //! Returns current editing mode.
- EditorMode mode() const;
-
- //! Sets the current editing mode.
- void setMode(EditorMode newMode);
-
- //! Set tile that is being drag'n'dropped.
- void setDragAndDropSourceTile(TrackTile * tile);
-
- //! Returns the tile being drag'n'dropped or nullptr.
- TrackTile * dragAndDropSourceTile() const;
-
- //! Set object that is being drag'n'dropped.
- void setDragAndDropObject(Object * object);
-
- //! Returns the object being drag'n'dropped or nullptr.
- Object * dragAndDropObject() const;
-
//! Set selected object.
void setSelectedObject(Object * object);
@@ -138,18 +109,6 @@
//! Returns the selected target node or nullptr.
TargetNode * selectedTargetNode() const;
- //! Set target node that is being drag'n'dropped.
- void setDragAndDropTargetNode(TargetNode * tnode);
-
- //! Returns the target node being drag'n'dropped or nullptr.
- TargetNode * dragAndDropTargetNode() const;
-
- //! Get source pos of the drag'n'drop.
- QPointF dragAndDropSourcePos() const;
-
- //! Set source pos of the drag'n'drop.
- void setDragAndDropSourcePos(QPointF pos);
-
//! Add tiles in current track data object to the scene.
void addTilesToScene();
@@ -167,6 +126,10 @@
unsigned int activeRow() const;
+ void setCurrentScale(int currentScale);
+
+ int currentScale() const;
+
private:
EditorData(const EditorData & e);
@@ -182,33 +145,28 @@
void removeTargetNodesFromScene();
+ DragAndDropStore m_dadStore;
+
TrackIO m_trackIO;
TrackDataPtr m_trackData;
UndoStack m_undoStack;
- EditorMode m_mode;
-
- TrackTile * m_dragAndDropSourceTile = nullptr;
-
- Object * m_dragAndDropObject = nullptr;
-
Object * m_selectedObject = nullptr;
TargetNode * m_selectedTargetNode = nullptr;
- TargetNode * m_dragAndDropTargetNode = nullptr;
-
- QPointF m_dragAndDropSourcePos;
-
- MainWindow * m_mainWindow = nullptr;
+ Mediator & m_mediator;
std::vector<QGraphicsLineItem *> m_targetNodes;
unsigned int m_activeColumn = 0;
unsigned int m_activeRow = 0;
+
+ // Scale percentage
+ int m_currentScale = 50;
};
#endif // EDITORDATA_HPP
diff -Nuar a/src/editor/editormode.hpp b/src/editor/editormode.hpp
--- a/src/editor/editormode.hpp 1970-01-01 02:00:00.000000000 +0200
+++ b/src/editor/editormode.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -0,0 +1,29 @@
+// This file is part of Dust Racing 2D.
+// Copyright (C) 2018 Jussi Lind <jussi.lind@iki.fi>
+//
+// Dust Racing 2D is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Dust Racing 2D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EDITORMODE_HPP
+#define EDITORMODE_HPP
+
+//! Editing modes.
+enum class EditorMode
+{
+ None,
+ SetRoute,
+ SetTileType,
+ AddObject,
+ EraseObject
+};
+
+#endif // EDITORMODE_HPP
diff -Nuar a/src/editor/editor.pro b/src/editor/editor.pro
--- a/src/editor/editor.pro 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/editor.pro 2018-02-11 08:22:08.000000000 +0300
@@ -29,11 +29,14 @@
../common/userexception.hpp \
aboutdlg.hpp \
application.hpp \
+ draganddropstore.hpp \
editordata.hpp \
- editorscene.hpp \
editorview.hpp \
+ editormode.hpp \
+ floodfill.hpp \
mainwindow.hpp \
map.hpp \
+ mediator.hpp \
newtrackdialog.hpp \
object.hpp \
objectfactory.hpp \
@@ -60,12 +63,14 @@
../common/tracktilebase.cpp \
aboutdlg.cpp \
application.cpp \
+ draganddropstore.cpp \
editordata.cpp \
- editorscene.cpp \
editorview.cpp \
+ floodfill.cpp \
main.cpp \
mainwindow.cpp \
map.cpp \
+ mediator.cpp \
newtrackdialog.cpp \
object.cpp \
objectfactory.cpp \
diff -Nuar a/src/editor/editorscene.cpp b/src/editor/editorscene.cpp
--- a/src/editor/editorscene.cpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/editorscene.cpp 1970-01-01 02:00:00.000000000 +0200
@@ -1,20 +0,0 @@
-// This file is part of Dust Racing 2D.
-// Copyright (C) 2011 Jussi Lind <jussi.lind@iki.fi>
-//
-// Dust Racing 2D is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// Dust Racing 2D is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
-
-#include "editorscene.hpp"
-
-EditorScene::EditorScene(QObject * parent) :
- QGraphicsScene(parent)
-{}
diff -Nuar a/src/editor/editorscene.hpp b/src/editor/editorscene.hpp
--- a/src/editor/editorscene.hpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/editorscene.hpp 1970-01-01 02:00:00.000000000 +0200
@@ -1,32 +0,0 @@
-// This file is part of Dust Racing 2D.
-// Copyright (C) 2011 Jussi Lind <jussi.lind@iki.fi>
-//
-// Dust Racing 2D is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// Dust Racing 2D is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
-
-#ifndef EDITORSCENE_HPP
-#define EDITORSCENE_HPP
-
-#include <QGraphicsScene>
-
-//! Graphics scene of the editor.
-class EditorScene : public QGraphicsScene
-{
- Q_OBJECT
-
-public:
-
- //! Constructor.
- explicit EditorScene(QObject * parent = nullptr);
-};
-
-#endif // EDITORSCENE_HPP
diff -Nuar a/src/editor/editorview.cpp b/src/editor/editorview.cpp
--- a/src/editor/editorview.cpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/editorview.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -20,9 +20,11 @@
#include <QString>
#include <QTransform>
-#include "editordata.hpp"
#include "editorview.hpp"
-#include "mainwindow.hpp"
+
+#include "draganddropstore.hpp"
+#include "editormode.hpp"
+#include "mediator.hpp"
#include "object.hpp"
#include "objectfactory.hpp"
#include "objectmodelloader.hpp"
@@ -35,9 +37,8 @@
#include <cassert>
#include <cstdlib>
-EditorView::EditorView(EditorData & editorData, QWidget * parent)
-: QGraphicsView(parent)
-, m_editorData(editorData)
+EditorView::EditorView(Mediator & mediator)
+ : m_mediator(mediator)
{
createTileContextMenuActions();
createObjectContextMenuActions();
@@ -49,8 +50,8 @@
const QRectF newSceneRect(
0,
0,
- m_editorData.trackData()->map().cols() * TrackTile::TILE_W,
- m_editorData.trackData()->map().rows() * TrackTile::TILE_H);
+ m_mediator.cols() * TrackTile::TILE_W,
+ m_mediator.rows() * TrackTile::TILE_H);
setSceneRect(newSceneRect);
@@ -69,45 +70,22 @@
}
// Tile drag'n'drop active?
- if (auto sourceTile = m_editorData.dragAndDropSourceTile())
+ if (auto sourceTile = m_mediator.dadStore().dragAndDropSourceTile())
{
sourceTile->setPos(mappedPos);
}
// Object drag'n'drop active?
- else if (auto object = m_editorData.dragAndDropObject())
+ else if (auto object = m_mediator.dadStore().dragAndDropObject())
{
object->setLocation(mappedPos);
}
// Target node drag'n'drop active?
- else if (auto tnode = m_editorData.dragAndDropTargetNode())
+ else if (auto tnode = m_mediator.dadStore().dragAndDropTargetNode())
{
tnode->setLocation(mappedPos);
}
- updateCoordinates(mappedPos);
- }
-}
-
-void EditorView::updateCoordinates(QPointF mappedPos)
-{
- if (m_editorData.trackData())
- {
- const int maxCols = static_cast<int>(m_editorData.trackData()->map().cols());
- int column = mappedPos.x() / TrackTile::TILE_W;
- column = column >= maxCols ? maxCols - 1 : column;
- column = column < 0 ? 0 : column;
-
- const int maxRows = static_cast<int>(m_editorData.trackData()->map().rows());
- int row = mappedPos.y() / TrackTile::TILE_H;
- row = row >= maxRows ? maxRows - 1 : row;
- row = row < 0 ? 0 : row;
-
- m_editorData.setActiveRow(static_cast<unsigned int>(row));
- m_editorData.setActiveColumn(static_cast<unsigned int>(column));
-
- QString coordinates("X: %1 Y: %2 I: %3 J: %4");
- coordinates = coordinates.arg(mappedPos.x()).arg(mappedPos.y()).arg(column).arg(row);
- MainWindow::instance()->statusBar()->showMessage(coordinates);
+ m_mediator.updateCoordinates(mappedPos);
}
}
@@ -121,7 +99,7 @@
if (TrackTile * tile =
dynamic_cast<TrackTile *>(scene()->itemAt(mapToScene(m_clickedPos), QTransform())))
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
tile->rotate90CW();
}
});
@@ -133,28 +111,28 @@
if (auto tile =
dynamic_cast<TrackTile *>(scene()->itemAt(mapToScene(m_clickedPos), QTransform())))
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
tile->rotate90CCW();
}
});
m_clearComputerHint = new QAction(QWidget::tr("Clear computer hint"), &m_tileContextMenu);
QObject::connect(m_clearComputerHint, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
setComputerHint(TrackTileBase::CH_NONE);
});
m_setComputerHintBrakeHard = new QAction(
QWidget::tr("Set computer hint 'brake hard'.."), &m_tileContextMenu);
QObject::connect(m_setComputerHintBrakeHard, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
setComputerHint(TrackTileBase::CH_BRAKE_HARD);
});
m_setComputerHintBrake = new QAction(
QWidget::tr("Set computer hint 'brake'.."), &m_tileContextMenu);
QObject::connect(m_setComputerHintBrake, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
setComputerHint(TrackTileBase::CH_BRAKE);
});
@@ -164,7 +142,7 @@
QObject::connect(m_excludeFromMinimap, &QAction::changed, [this] () {
if (auto tile = dynamic_cast<TrackTile *>(scene()->itemAt(mapToScene(this->m_clickedPos), QTransform())))
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
tile->setExcludeFromMinimap(this->m_excludeFromMinimap->isChecked());
}
});
@@ -172,9 +150,8 @@
auto insertRowBefore = new QAction(
QWidget::tr("Insert row before.."), &m_tileContextMenu);
QObject::connect(insertRowBefore, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
- m_editorData.trackData()->insertRow(m_editorData.activeRow(), MapBase::InsertDirection::Before);
- m_editorData.addTilesToScene();
+ m_mediator.saveUndoPoint();
+ m_mediator.insertRowBefore();
updateSceneRect();
update();
});
@@ -182,9 +159,8 @@
auto insertRowAfter = new QAction(
QWidget::tr("Insert row after.."), &m_tileContextMenu);
QObject::connect(insertRowAfter, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
- m_editorData.trackData()->insertRow(m_editorData.activeRow(), MapBase::InsertDirection::After);
- m_editorData.addTilesToScene();
+ m_mediator.saveUndoPoint();
+ m_mediator.insertRowAfter();
updateSceneRect();
update();
});
@@ -192,11 +168,8 @@
m_deleteRow = new QAction(
QWidget::tr("Delete row.."), &m_tileContextMenu);
QObject::connect(m_deleteRow, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
- auto deleted = m_editorData.trackData()->deleteRow(m_editorData.activeRow());
- for (auto && tile : deleted) {
- m_editorData.removeTileFromScene(tile);
- }
+ m_mediator.saveUndoPoint();
+ m_mediator.deleteRow();
updateSceneRect();
update();
});
@@ -204,9 +177,8 @@
auto insertColBefore = new QAction(
QWidget::tr("Insert column before.."), &m_tileContextMenu);
QObject::connect(insertColBefore, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
- m_editorData.trackData()->insertColumn(m_editorData.activeColumn(), MapBase::InsertDirection::Before);
- m_editorData.addTilesToScene();
+ m_mediator.saveUndoPoint();
+ m_mediator.insertColumnBefore();
updateSceneRect();
update();
});
@@ -214,9 +186,8 @@
auto insertColAfter = new QAction(
QWidget::tr("Insert column after.."), &m_tileContextMenu);
QObject::connect(insertColAfter, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
- m_editorData.trackData()->insertColumn(m_editorData.activeColumn(), MapBase::InsertDirection::After);
- m_editorData.addTilesToScene();
+ m_mediator.saveUndoPoint();
+ m_mediator.insertColumnAfter();
updateSceneRect();
update();
});
@@ -224,11 +195,8 @@
m_deleteCol = new QAction(
QWidget::tr("Delete column.."), &m_tileContextMenu);
QObject::connect(m_deleteCol, &QAction::triggered, [this] () {
- m_editorData.saveUndoPoint();
- auto deleted = m_editorData.trackData()->deleteColumn(m_editorData.activeColumn());
- for (auto && tile : deleted) {
- m_editorData.removeTileFromScene(tile);
- }
+ m_mediator.saveUndoPoint();
+ m_mediator.deleteColumn();
updateSceneRect();
update();
});
@@ -260,9 +228,9 @@
RotateDialog dialog;
if (dialog.exec() == QDialog::Accepted)
{
- if (auto object = m_editorData.selectedObject())
+ if (auto object = m_mediator.selectedObject())
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
object->setRotation(static_cast<int>(dialog.angle() + object->rotation()) % 360);
}
@@ -273,9 +241,9 @@
m_forceStationaryAction = new QAction(dummy2, &m_tileContextMenu);
m_forceStationaryAction->setCheckable(true);
QObject::connect(m_forceStationaryAction, &QAction::changed, [this] () {
- if (auto object = m_editorData.selectedObject())
+ if (auto object = m_mediator.selectedObject())
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
object->setForceStationary(m_forceStationaryAction->isChecked());
}
});
@@ -291,12 +259,12 @@
const QString dummy1(QString(QWidget::tr("Set size..")));
auto setSize = new QAction(dummy1, &m_targetNodeContextMenu);
QObject::connect(setSize, &QAction::triggered, [this] () {
- if (auto tnode = m_editorData.selectedTargetNode())
+ if (auto tnode = m_mediator.selectedTargetNode())
{
TargetNodeSizeDlg dialog(tnode->size());
if (dialog.exec() == QDialog::Accepted)
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
tnode->setSize(dialog.targetNodeSize());
}
@@ -311,12 +279,11 @@
{
if (scene())
{
- m_clickedPos = event->pos();
+ m_clickedPos = event->pos();
m_clickedScenePos = mapToScene(m_clickedPos);
// Fetch all items at the location
- QList<QGraphicsItem *> items = scene()->items(
- m_clickedScenePos, Qt::IntersectsItemShape, Qt::DescendingOrder);
+ QList<QGraphicsItem *> items = scene()->items(m_clickedScenePos, Qt::IntersectsItemShape, Qt::DescendingOrder);
if (items.size())
{
@@ -351,7 +318,7 @@
void EditorView::eraseObjectAtCurrentClickedPos()
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
// Fetch all items at the location
QList<QGraphicsItem *> items = scene()->items(
@@ -363,9 +330,8 @@
{
if (auto object = dynamic_cast<Object *>(item))
{
- scene()->removeItem(object);
- m_editorData.trackData()->objects().remove(*object);
- m_editorData.setSelectedObject(nullptr);
+ m_mediator.removeObject(*object);
+ m_mediator.setSelectedObject(nullptr);
break;
}
}
@@ -373,26 +339,7 @@
void EditorView::addCurrentToolBarObjectToScene()
{
- if (QAction * action = MainWindow::instance()->currentToolBarAction())
- {
- if (scene())
- {
- m_editorData.saveUndoPoint();
-
- Object & object = ObjectFactory::createObject(action->data().toString());
- object.setLocation(m_clickedScenePos);
-
- if (MainWindow::instance()->randomlyRotateObjects())
- {
- object.setRotation(std::rand() % 360);
- }
-
- scene()->addItem(&object);
-
- m_editorData.trackData()->objects().add(ObjectBasePtr(&object));
- m_editorData.setSelectedObject(&object);
- }
- }
+ m_mediator.addCurrentToolBarObjectToScene(m_clickedScenePos);
}
void EditorView::handleMousePressEventOnObject(QMouseEvent & event, Object & object)
@@ -404,12 +351,12 @@
else if (event.button() == Qt::LeftButton)
{
// User is adding an object
- if (m_editorData.mode() == EditorData::EditorMode::AddObject)
+ if (m_mediator.mode() == EditorMode::AddObject)
{
addCurrentToolBarObjectToScene();
}
// User is erasing an object
- else if (m_editorData.mode() == EditorData::EditorMode::EraseObject)
+ else if (m_mediator.mode() == EditorMode::EraseObject)
{
eraseObjectAtCurrentClickedPos();
}
@@ -432,7 +379,7 @@
else if (event.button() == Qt::LeftButton)
{
// User is adding an object
- if (m_editorData.mode() == EditorData::EditorMode::AddObject)
+ if (m_mediator.mode() == EditorMode::AddObject)
{
addCurrentToolBarObjectToScene();
}
@@ -456,7 +403,7 @@
else if (event.button() == Qt::LeftButton)
{
// User is adding an object
- if (m_editorData.mode() == EditorData::EditorMode::AddObject)
+ if (m_mediator.mode() == EditorMode::AddObject)
{
addCurrentToolBarObjectToScene();
}
@@ -472,13 +419,13 @@
void EditorView::handleLeftButtonClickOnObject(Object & object)
{
// User is initiating a drag'n'drop
- if (m_editorData.mode() == EditorData::EditorMode::None)
+ if (m_mediator.mode() == EditorMode::None)
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
object.setZValue(object.zValue() + 1);
- m_editorData.setDragAndDropObject(&object);
- m_editorData.setSelectedObject(&object);
+ m_mediator.dadStore().setDragAndDropObject(&object);
+ m_mediator.setSelectedObject(&object);
// Change cursor to the closed hand cursor.
QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
@@ -488,34 +435,34 @@
void EditorView::handleLeftButtonClickOnTargetNode(TargetNode & tnode)
{
// User is initiating a drag'n'drop
- if (m_editorData.mode() == EditorData::EditorMode::None)
+ if (m_mediator.mode() == EditorMode::None)
{
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
tnode.setZValue(tnode.zValue() + 1);
- m_editorData.setDragAndDropTargetNode(&tnode);
+ m_mediator.dadStore().setDragAndDropTargetNode(&tnode);
// Change cursor to the closed hand cursor.
QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
}
// It's not possible to make nodes overlap if not handled also here.
- else if (m_editorData.mode() == EditorData::EditorMode::SetRoute)
+ else if (m_mediator.mode() == EditorMode::SetRoute)
{
- m_editorData.pushNewTargetNodeToRoute(m_clickedScenePos);
+ m_mediator.pushNewTargetNodeToRoute(m_clickedScenePos);
}
}
void EditorView::handleLeftButtonClickOnTile(TrackTile & tile)
{
// User is defining the route
- if (m_editorData.mode() == EditorData::EditorMode::SetRoute)
+ if (m_mediator.mode() == EditorMode::SetRoute)
{
- m_editorData.pushNewTargetNodeToRoute(m_clickedScenePos);
+ m_mediator.pushNewTargetNodeToRoute(m_clickedScenePos);
}
// User is setting the tile type
- else if (m_editorData.mode() == EditorData::EditorMode::SetTileType)
+ else if (m_mediator.mode() == EditorMode::SetTileType)
{
- if (QAction * action = MainWindow::instance()->currentToolBarAction())
+ if (QAction * action = m_mediator.currentToolBarAction())
{
Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
@@ -525,7 +472,7 @@
if (typeToFill != action->data().toString())
{
- doFloodFill(tile, action, typeToFill);
+ m_mediator.floodFill(tile, action, typeToFill);
}
}
else
@@ -535,11 +482,11 @@
}
}
// User is initiating a drag'n'drop
- else if (m_editorData.mode() == EditorData::EditorMode::None)
+ else if (m_mediator.mode() == EditorMode::None)
{
tile.setZValue(tile.zValue() + 1);
- m_editorData.setDragAndDropSourceTile(&tile);
- m_editorData.setDragAndDropSourcePos(tile.pos());
+ m_mediator.dadStore().setDragAndDropSourceTile(&tile);
+ m_mediator.dadStore().setDragAndDropSourcePos(tile.pos());
// Change cursor to the closed hand cursor.
QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
@@ -570,11 +517,8 @@
m_excludeFromMinimap->setChecked(tile.excludeFromMinimap());
- if (m_editorData.trackData())
- {
- m_deleteCol->setEnabled(m_editorData.trackData()->map().cols() > 2);
- m_deleteRow->setEnabled(m_editorData.trackData()->map().rows() > 2);
- }
+ m_deleteCol->setEnabled(m_mediator.cols());
+ m_deleteRow->setEnabled(m_mediator.rows());
const QPoint globalPos = mapToGlobal(m_clickedPos);
m_tileContextMenu.exec(globalPos);
@@ -593,7 +537,7 @@
void EditorView::handleRightButtonClickOnObject(Object & object)
{
- m_editorData.setSelectedObject(&object);
+ m_mediator.setSelectedObject(&object);
m_forceStationaryAction->setChecked(object.forceStationary());
@@ -608,7 +552,7 @@
void EditorView::handleRightButtonClickOnTargetNode(TargetNode & tnode)
{
- m_editorData.setSelectedTargetNode(&tnode);
+ m_mediator.setSelectedTargetNode(&tnode);
openTargetNodeContextMenu();
}
@@ -622,26 +566,26 @@
void EditorView::keyPressEvent(QKeyEvent * event)
{
- if (auto object = m_editorData.selectedObject())
+ if (auto object = m_mediator.selectedObject())
{
if (!event->isAutoRepeat())
{
switch (event->key())
{
case Qt::Key_Left:
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
object->setLocation(QPointF(object->location().x() - 1, object->location().y()));
break;
case Qt::Key_Right:
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
object->setLocation(QPointF(object->location().x() + 1, object->location().y()));
break;
case Qt::Key_Up:
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
object->setLocation(QPointF(object->location().x(), object->location().y() - 1));
break;
case Qt::Key_Down:
- m_editorData.saveUndoPoint();
+ m_mediator.saveUndoPoint();
object->setLocation(QPointF(object->location().x(), object->location().y() + 1));
break;
default:
@@ -653,81 +597,72 @@
void EditorView::handleTileDragRelease(QMouseEvent * event)
{
- if (scene())
+ // Tile drag'n'drop active?
+ if (auto sourceTile = m_mediator.dadStore().dragAndDropSourceTile())
{
- // Tile drag'n'drop active?
- if (auto sourceTile = m_editorData.dragAndDropSourceTile())
+ // Determine the dest tile
+ auto destTile = sourceTile;
+ QList<QGraphicsItem *> items = scene()->items(mapToScene(event->pos()));
+ for (QGraphicsItem * item : items)
{
- // Determine the dest tile
- auto destTile = sourceTile;
- QList<QGraphicsItem *> items = scene()->items(mapToScene(event->pos()));
- for (QGraphicsItem * item : items)
+ auto testTile = dynamic_cast<TrackTile *>(item);
+ if (testTile && testTile != sourceTile)
{
- auto testTile = dynamic_cast<TrackTile *>(item);
- if (testTile && testTile != sourceTile)
- {
- destTile = testTile;
- break;
- }
+ destTile = testTile;
+ break;
}
+ }
- // Swap tiles
- sourceTile->swap(*destTile);
+ // Swap tiles
+ sourceTile->swap(*destTile);
- // Restore position
- sourceTile->setPos(m_editorData.dragAndDropSourcePos());
- sourceTile->setZValue(sourceTile->zValue() - 1);
- destTile->setZValue(sourceTile->zValue());
+ // Restore position
+ sourceTile->setPos(m_mediator.dadStore().dragAndDropSourcePos());
+ sourceTile->setZValue(sourceTile->zValue() - 1);
+ destTile->setZValue(sourceTile->zValue());
- update();
+ update();
- m_editorData.setDragAndDropSourceTile(nullptr);
+ m_mediator.dadStore().clear();
- // Restore the cursor.
- QApplication::restoreOverrideCursor();
- }
+ // Restore the cursor.
+ QApplication::restoreOverrideCursor();
}
}
void EditorView::handleObjectDragRelease(QMouseEvent * event)
{
- if (scene())
+ // Object drag'n'drop active?
+ if (auto object = m_mediator.dadStore().dragAndDropObject())
{
- // Object drag'n'drop active?
- if (auto object = m_editorData.dragAndDropObject())
- {
- // Set the new position position
- object->setLocation(mapToScene(event->pos()));
- object->setZValue(object->zValue() - 1);
+ // Set the new position position
+ object->setLocation(mapToScene(event->pos()));
+ object->setZValue(object->zValue() - 1);
- update();
+ update();
- m_editorData.setDragAndDropObject(nullptr);
+ m_mediator.dadStore().clear();
- // Restore the cursor.
- QApplication::restoreOverrideCursor();
- }
+ // Restore the cursor.
+ QApplication::restoreOverrideCursor();
}
}
void EditorView::handleTargetNodeDragRelease(QMouseEvent * event)
{
- if (scene())
+ // Target node drag'n'drop active?
+ if (auto tnode = m_mediator.dadStore().dragAndDropTargetNode())
{
- // Target node drag'n'drop active?
- if (auto tnode = m_editorData.dragAndDropTargetNode())
- {
- // Set the new position position
- tnode->setLocation(mapToScene(event->pos()));
- tnode->setZValue(tnode->zValue() - 1);
+ // Set the new position position
+ tnode->setLocation(mapToScene(event->pos()));
+ tnode->setZValue(tnode->zValue() - 1);
- update();
+ update();
- m_editorData.setDragAndDropTargetNode(nullptr);
+ m_mediator.dadStore().clear();
- // Restore the cursor.
- QApplication::restoreOverrideCursor();
- }
+ // Restore the cursor.
+ QApplication::restoreOverrideCursor();
}
}
@@ -735,58 +670,14 @@
{
if (auto tile = dynamic_cast<TrackTile *>(scene()->itemAt(mapToScene(m_clickedPos), QTransform())))
{
- m_editorData.saveUndoPoint();
-
+ m_mediator.saveUndoPoint();
tile->setComputerHint(hint);
}
}
-void EditorView::doFloodFill(TrackTile & tile, QAction * action, QString typeToFill)
-{
- m_editorData.saveUndoPoint();
-
- floodFill(tile, action, typeToFill);
-}
-
-void EditorView::floodFill(TrackTile & tile, QAction * action, const QString & typeToFill)
-{
- static const int DIRECTION_COUNT = 4;
-
- // Coordinates of neighbor tiles can be calculated by adding these
- // adjustments to tile coordinates.
- static const QPoint neighborAdjustments[DIRECTION_COUNT] =
- {
- QPoint( 1, 0), // right
- QPoint( 0, -1), // up
- QPoint(-1, 0), // left
- QPoint( 0, 1) // down
- };
-
- setTileType(tile, action);
-
- MapBase & map = m_editorData.trackData()->map();
- QPoint location = tile.matrixLocation();
-
- for (int i = 0; i < DIRECTION_COUNT; ++i)
- {
- int x = location.x() + neighborAdjustments[i].x();
- int y = location.y() + neighborAdjustments[i].y();
-
- if (x >= 0 && y >= 0)
- {
- auto tile = std::dynamic_pointer_cast<TrackTile>(map.getTile(x, y));
- if (tile && tile->tileType() == typeToFill)
- {
- floodFill(*(tile.get()), action, typeToFill);
- }
- }
- }
-}
-
void EditorView::changeTileType(TrackTile & tile, QAction * action)
{
- m_editorData.saveUndoPoint();
-
+ m_mediator.saveUndoPoint();
setTileType(tile, action);
}
@@ -795,3 +686,15 @@
tile.setTileType(action->data().toString());
tile.setPixmap(action->icon().pixmap(TrackTile::TILE_W, TrackTile::TILE_H));
}
+
+void EditorView::wheelEvent(QWheelEvent * event)
+{
+ if (event->modifiers() & Qt::ControlModifier)
+ {
+ m_mediator.mouseWheelZoom(event->delta());
+ }
+ else
+ {
+ QGraphicsView::wheelEvent(event);
+ }
+}
diff -Nuar a/src/editor/editorview.hpp b/src/editor/editorview.hpp
--- a/src/editor/editorview.hpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/editorview.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -20,10 +20,10 @@
#include <QMenu>
#include "../common/tracktilebase.hpp"
+class Mediator;
class QAction;
class QMouseEvent;
class QPaintEvent;
-class EditorData;
class Object;
class ObjectModelLoaderoader;
class TargetNode;
@@ -35,7 +35,7 @@
public:
- explicit EditorView(EditorData & editorData, QWidget * parent = 0);
+ explicit EditorView(Mediator & mediator);
void updateSceneRect();
@@ -49,6 +49,8 @@
void keyPressEvent(QKeyEvent * event) override;
+ void wheelEvent(QWheelEvent * event) override;
+
private:
void addCurrentToolBarObjectToScene();
@@ -61,12 +63,8 @@
void createTargetNodeContextMenuActions();
- void doFloodFill(TrackTile & tile, QAction * action, QString typeToFill);
-
void eraseObjectAtCurrentClickedPos();
- void floodFill(TrackTile & tile, QAction * action, const QString & typeToFill);
-
void handleMousePressEventOnTile(QMouseEvent & event, TrackTile & tile);
void handleLeftButtonClickOnTile(TrackTile & tile);
@@ -99,8 +97,6 @@
void setComputerHint(TrackTileBase::ComputerHint hint);
- void updateCoordinates(QPointF mappedPos);
-
static void setTileType(TrackTile & tile, QAction * action);
QMenu m_tileContextMenu;
@@ -127,7 +123,7 @@
QAction * m_forceStationaryAction = nullptr;
- EditorData & m_editorData;
+ Mediator & m_mediator;
};
#endif // EDITORVIEW_HPP
diff -Nuar a/src/editor/floodfill.cpp b/src/editor/floodfill.cpp
--- a/src/editor/floodfill.cpp 1970-01-01 02:00:00.000000000 +0200
+++ b/src/editor/floodfill.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -0,0 +1,62 @@
+// This file is part of Dust Racing 2D.
+// Copyright (C) 2018 Jussi Lind <jussi.lind@iki.fi>
+//
+// Dust Racing 2D is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Dust Racing 2D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
+
+#include "floodfill.hpp"
+#include "map.hpp"
+#include "tracktile.hpp"
+
+#include <QAction>
+
+namespace FloodFill {
+void setTileType(TrackTile & tile, QAction * action)
+{
+ tile.setTileType(action->data().toString());
+ tile.setPixmap(action->icon().pixmap(TrackTile::TILE_W, TrackTile::TILE_H));
+}
+}
+
+void FloodFill::floodFill(TrackTile & tile, QAction * action, const QString & typeToFill, MapBase & map)
+{
+ static const int DIRECTION_COUNT = 4;
+
+ // Coordinates of neighbor tiles can be calculated by adding these
+ // adjustments to tile coordinates.
+ static const QPoint neighborAdjustments[DIRECTION_COUNT] =
+ {
+ QPoint( 1, 0), // right
+ QPoint( 0, -1), // up
+ QPoint(-1, 0), // left
+ QPoint( 0, 1) // down
+ };
+
+ setTileType(tile, action);
+
+ QPoint location = tile.matrixLocation();
+
+ for (int i = 0; i < DIRECTION_COUNT; ++i)
+ {
+ int x = location.x() + neighborAdjustments[i].x();
+ int y = location.y() + neighborAdjustments[i].y();
+
+ if (x >= 0 && y >= 0)
+ {
+ auto tile = std::dynamic_pointer_cast<TrackTile>(map.getTile(x, y));
+ if (tile && tile->tileType() == typeToFill)
+ {
+ FloodFill::floodFill(*(tile.get()), action, typeToFill, map);
+ }
+ }
+ }
+}
diff -Nuar a/src/editor/floodfill.hpp b/src/editor/floodfill.hpp
--- a/src/editor/floodfill.hpp 1970-01-01 02:00:00.000000000 +0200
+++ b/src/editor/floodfill.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -0,0 +1,28 @@
+// This file is part of Dust Racing 2D.
+// Copyright (C) 2018 Jussi Lind <jussi.lind@iki.fi>
+//
+// Dust Racing 2D is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Dust Racing 2D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef FLOODFILL_HPP
+#define FLOODFILL_HPP
+
+class MapBase;
+class QAction;
+class QString;
+class TrackTile;
+
+namespace FloodFill {
+void floodFill(TrackTile & tile, QAction * action, const QString & typeToFill, MapBase & map);
+}
+
+#endif // FLOODFILL_HPP
diff -Nuar a/src/editor/mainwindow.cpp b/src/editor/mainwindow.cpp
--- a/src/editor/mainwindow.cpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/mainwindow.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -26,7 +26,7 @@
#include "tracktile.hpp"
#include "editordata.hpp"
#include "editorview.hpp"
-#include "editorscene.hpp"
+#include "mediator.hpp"
#include "newtrackdialog.hpp"
#include <QAction>
@@ -55,26 +55,15 @@
MainWindow * MainWindow::m_instance = nullptr;
-namespace
-{
- const char * SETTINGS_GROUP = "MainWindow";
- const unsigned int MIN_ZOOM = 0;
- const unsigned int MAX_ZOOM = 200;
- const unsigned int INI_ZOOM = 100;
- const int CONSOLE_HEIGHT = 64;
-}
-
MainWindow::MainWindow(QString trackFile)
: m_objectModelLoader(new ObjectModelLoader)
, m_aboutDlg(new AboutDlg(this))
-, m_editorData(new EditorData(this))
-, m_editorScene(new EditorScene(this))
-, m_editorView(new EditorView(*m_editorData, this))
, m_console(new QTextEdit(this))
, m_scaleSlider(new QSlider(Qt::Horizontal, this))
, m_toolBar(new QToolBar(this))
, m_randomRotationCheck(new QCheckBox(tr("Randomly rotate objects"), this))
, m_argTrackFile(trackFile)
+, m_mediator(new Mediator(*this))
{
if (!m_instance)
{
@@ -122,6 +111,11 @@
}
}
+void MainWindow::updateScaleSlider(int value)
+{
+ m_scaleSlider->setValue(value);
+}
+
void MainWindow::showTip()
{
QMessageBox::information(
@@ -138,7 +132,7 @@
QSettings settings;
// Read dialog size data
- settings.beginGroup(SETTINGS_GROUP);
+ settings.beginGroup(m_settingsGroup);
resize(settings.value("size", QSize(640, 480)).toSize());
settings.endGroup();
@@ -147,15 +141,15 @@
move(geometry.width() / 2 - width() / 2,
geometry.height() / 2 - height() / 2);
- // Populate menu bar with actions
+ m_mediator->initScene();
+
populateMenuBar();
- // Set scene to the view
- m_editorView->setScene(m_editorScene);
- m_editorView->setSizePolicy(QSizePolicy::Preferred,
- QSizePolicy::Expanding);
- m_editorView->setMouseTracking(true);
+ createWidgets();
+}
+void MainWindow::createWidgets()
+{
// Create a splitter
QSplitter * splitter = new QSplitter(this);
splitter->setOrientation(Qt::Vertical);
@@ -164,7 +158,7 @@
QVBoxLayout * centralLayout = new QVBoxLayout;
QHBoxLayout * viewToolBarLayout = new QHBoxLayout;
m_toolBar->setOrientation(Qt::Vertical);
- viewToolBarLayout->addWidget(m_editorView);
+ m_mediator->addViewToLayout(viewToolBarLayout);
viewToolBarLayout->addWidget(m_toolBar);
centralLayout->addLayout(viewToolBarLayout);
@@ -172,8 +166,8 @@
populateToolBar();
// Add zoom slider to the layout
- m_scaleSlider->setRange(MIN_ZOOM, MAX_ZOOM);
- m_scaleSlider->setValue(INI_ZOOM);
+ m_scaleSlider->setRange(m_minZoom, m_maxZoom);
+ m_scaleSlider->setValue(m_initZoom);
m_scaleSlider->setTracking(false);
m_scaleSlider->setTickInterval(10);
m_scaleSlider->setTickPosition(QSlider::TicksBelow);
@@ -207,7 +201,7 @@
setCentralWidget(splitter);
QList<int> sizes;
- sizes << height() - CONSOLE_HEIGHT << CONSOLE_HEIGHT;
+ sizes << height() - m_consoleHeight << m_consoleHeight;
splitter->setSizes(sizes);
}
@@ -268,21 +262,6 @@
return MainWindow::m_instance;
}
-EditorView & MainWindow::editorView() const
-{
- return *m_editorView;
-}
-
-EditorScene & MainWindow::editorScene() const
-{
- return *m_editorScene;
-}
-
-EditorData & MainWindow::editorData() const
-{
- return *m_editorData;
-}
-
ObjectModelLoader & MainWindow::objectModelLoader() const
{
return *m_objectModelLoader;
@@ -295,11 +274,7 @@
void MainWindow::updateScale(int value)
{
- qreal scale = static_cast<qreal>(value) / 100;
-
- QTransform transform;
- transform.scale(scale, scale);
- m_editorView->setTransform(transform);
+ m_mediator->setScale(value);
console(QString(tr("Scale set to %1%")).arg(value));
}
@@ -310,7 +285,7 @@
QSettings settings;
// Save window size
- settings.beginGroup(SETTINGS_GROUP);
+ settings.beginGroup(m_settingsGroup);
settings.setValue("size", size());
settings.endGroup();
@@ -362,12 +337,12 @@
m_undoAction->setShortcut(QKeySequence("Ctrl+Z"));
editMenu->addAction(m_undoAction);
connect(m_undoAction, &QAction::triggered, [this](){
- m_editorData->undo();
+ m_mediator->undo();
setupTrackAfterUndoOrRedo();
- m_undoAction->setEnabled(m_editorData->isUndoable());
- m_redoAction->setEnabled(m_editorData->isRedoable());
+ m_undoAction->setEnabled(m_mediator->isUndoable());
+ m_redoAction->setEnabled(m_mediator->isRedoable());
});
m_undoAction->setEnabled(false);
@@ -376,27 +351,15 @@
m_redoAction->setShortcut(QKeySequence("Ctrl+Shift+Z"));
editMenu->addAction(m_redoAction);
connect(m_redoAction, &QAction::triggered, [this](){
- m_editorData->redo();
+ m_mediator->redo();
setupTrackAfterUndoOrRedo();
- m_undoAction->setEnabled(m_editorData->isUndoable());
- m_redoAction->setEnabled(m_editorData->isRedoable());
+ m_undoAction->setEnabled(m_mediator->isUndoable());
+ m_redoAction->setEnabled(m_mediator->isRedoable());
});
m_redoAction->setEnabled(false);
- // Add "enlarge hor size"-action
- m_enlargeHorSize = new QAction(tr("Enlarge hor size"), this);
- editMenu->addAction(m_enlargeHorSize);
- connect(m_enlargeHorSize, SIGNAL(triggered()), this, SLOT(enlargeHorSize()));
- m_enlargeHorSize->setEnabled(false);
-
- // Add "enlarge ver size"-action
- m_enlargeVerSize = new QAction(tr("Enlarge ver size"), this);
- editMenu->addAction(m_enlargeVerSize);
- connect(m_enlargeVerSize, SIGNAL(triggered()), this, SLOT(enlargeVerSize()));
- m_enlargeVerSize->setEnabled(false);
-
// Add "Set track properties"-action
m_setTrackPropertiesAction = new QAction(tr("&Set properties.."), this);
editMenu->addAction(m_setTrackPropertiesAction);
@@ -460,8 +423,6 @@
{
if (action != m_currentToolBarAction)
{
- assert(m_editorData);
-
m_currentToolBarAction = action;
// Select-action
@@ -474,14 +435,14 @@
{
QApplication::restoreOverrideCursor();
QApplication::setOverrideCursor(QCursor(action->icon().pixmap(32, 32)));
- m_editorData->setMode(EditorData::EditorMode::EraseObject);
+ m_mediator->setMode(EditorMode::EraseObject);
}
// The user wants to clear a tile.
else if (action->data() == "clear")
{
QApplication::restoreOverrideCursor();
QApplication::setOverrideCursor(QCursor(action->icon().pixmap(32, 32)));
- m_editorData->setMode(EditorData::EditorMode::SetTileType);
+ m_mediator->setMode(EditorMode::SetTileType);
}
// The user wants to set a tile type or clear it.
else if (m_objectModelLoader->getCategoryByRole(
@@ -489,7 +450,7 @@
{
QApplication::restoreOverrideCursor();
QApplication::setOverrideCursor(QCursor(action->icon().pixmap(32, 32)));
- m_editorData->setMode(EditorData::EditorMode::SetTileType);
+ m_mediator->setMode(EditorMode::SetTileType);
}
// The user wants to add an object to the scene.
else if (m_objectModelLoader->getCategoryByRole(
@@ -497,7 +458,7 @@
{
QApplication::restoreOverrideCursor();
QApplication::setOverrideCursor(QCursor(QPixmap(":/cursor2.png")));
- m_editorData->setMode(EditorData::EditorMode::AddObject);
+ m_mediator->setMode(EditorMode::AddObject);
}
}
else
@@ -514,7 +475,7 @@
// Load recent path
QSettings settings;
- settings.beginGroup(SETTINGS_GROUP);
+ settings.beginGroup(m_settingsGroup);
QString path = settings.value("recentPath",
QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).toString();
settings.endGroup();
@@ -539,9 +500,8 @@
void MainWindow::clearRoute()
{
- assert(m_editorData);
- m_editorData->saveUndoPoint();
- m_editorData->clearRoute();
+ m_mediator->clearRoute();
+
m_clearRouteAction->setEnabled(false);
}
@@ -553,13 +513,11 @@
return false;
}
- assert(m_editorData);
-
// Undo stack will be cleared.
m_undoAction->setEnabled(false);
m_redoAction->setEnabled(false);
- if (m_editorData->loadTrackData(fileName))
+ if (m_mediator->openTrack(fileName))
{
console(QString(tr("Track '%1' opened.").arg(fileName)));
@@ -568,7 +526,7 @@
// Save recent path
QSettings settings;
- settings.beginGroup(SETTINGS_GROUP);
+ settings.beginGroup(m_settingsGroup);
settings.setValue("recentPath", fileName);
settings.endGroup();
@@ -576,21 +534,11 @@
setActionStatesOnNewTrack();
- delete m_editorScene;
- m_editorScene = new EditorScene;
-
- m_editorView->setScene(m_editorScene);
- m_editorView->updateSceneRect();
-
- m_editorData->addTilesToScene();
- m_editorData->addObjectsToScene();
- m_editorData->addExistingRouteToScene();
-
fitScale();
m_saved = true;
- m_clearRouteAction->setEnabled(m_editorData->trackData()->route().numNodes());
+ m_clearRouteAction->setEnabled(m_mediator->routeHasNodes());
return true;
}
@@ -603,23 +551,87 @@
return false;
}
-void MainWindow::setupTrackAfterUndoOrRedo()
+void MainWindow::beginSetRoute()
{
- m_saveAction->setEnabled(true);
+ if (m_mediator->beginSetRoute())
+ {
+ console(tr("Set route: begin."));
+ QMessageBox::information(
+ this,
+ tr("Set route, checkpoints and driving lines."),
+ tr("Setting the route defines checkpoints for the cars so\n"
+ "that no shortcuts can be taken. It also defines\n"
+ "driving lines for the computer players.\n\n"
+ "Click on the tiles one by one and make a closed loop\n"
+ "with the target nodes. You can adjust the nodes afterwads.\n"
+ "Start from the first tile after the finish line tile\n"
+ "to make the lap detection and timing work correctly.\n"
+ "Click on the first node again to finish."));
+ }
+ else
+ {
+ console(tr("Set route: not a valid track."));
+ QMessageBox::critical(this, tr("Set route"), tr("Invalid track. Route cannot be set."));
+ }
+}
- setActionStatesOnNewTrack();
+void MainWindow::clearEditMode()
+{
+ m_mediator->clearEditMode();
+}
+
+void MainWindow::console(QString text)
+{
+ QDateTime date = QDateTime::currentDateTime();
+ m_console->append(QString("(") + date.toString("hh:mm:ss") + "): " + text);
+}
+
+void MainWindow::enableUndo(bool enable)
+{
+ m_undoAction->setEnabled(enable);
+}
+
+void MainWindow::endSetRoute()
+{
+ m_mediator->endSetRoute();
+
+ m_clearRouteAction->setEnabled(m_mediator->routeHasNodes());
+
+ console(tr("Set route: route finished."));
+}
- delete m_editorScene;
- m_editorScene = new EditorScene;
+void MainWindow::fitScale()
+{
+ m_scaleSlider->setValue(m_mediator->fitScale());
+}
- m_editorView->setScene(m_editorScene);
- m_editorView->updateSceneRect();
+void MainWindow::initializeNewTrack()
+{
+ QString nameOut;
+ int colsOut, rowsOut;
+ if (m_mediator->initializeNewTrack(nameOut, colsOut, rowsOut))
+ {
+ // Undo stack has been cleared.
+ m_undoAction->setEnabled(false);
+ m_redoAction->setEnabled(false);
- m_editorData->addTilesToScene();
- m_editorData->addObjectsToScene();
- m_editorData->addExistingRouteToScene();
+ fitScale();
- m_clearRouteAction->setEnabled(m_editorData->trackData()->route().numNodes());
+ setActionStatesOnNewTrack();
+
+ setTitle(tr("New file"));
+
+ m_clearRouteAction->setEnabled(false);
+
+ m_saved = false;
+
+ console(QString(tr("A new track '%1' created. Columns: %2, Rows: %3."))
+ .arg(nameOut)
+ .arg(colsOut)
+ .arg(rowsOut));
+ }
+
+ QApplication::restoreOverrideCursor();
}
void MainWindow::saveTrack()
@@ -632,18 +644,15 @@
}
else
{
- assert(m_editorData);
- if (m_editorData->saveTrackData())
+ if (m_mediator->saveTrackData())
{
- console(QString(
- tr("Track '")) + m_editorData->trackData()->fileName() + tr("' saved."));
- setTitle(m_editorData->trackData()->fileName());
+ console(QString(tr("Track '")) + m_mediator->currentFileName() + tr("' saved."));
+ setTitle(m_mediator->currentFileName());
m_saved = true;
}
else
{
- console(QString(
- tr("Failed to save track '")) + m_editorData->trackData()->fileName() + "'.");
+ console(QString(tr("Failed to save track '")) + m_mediator->currentFileName() + "'.");
}
}
@@ -665,8 +674,7 @@
fileName += trackFileExtension;
}
- assert(m_editorData);
- if (m_editorData->saveTrackDataAs(fileName))
+ if (m_mediator->saveTrackDataAs(fileName))
{
console(QString(tr("Track '")) + fileName + tr("' saved."));
setTitle(fileName);
@@ -680,51 +688,15 @@
QApplication::restoreOverrideCursor();
}
-void MainWindow::initializeNewTrack()
+void MainWindow::setupTrackAfterUndoOrRedo()
{
- QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
-
- // Show a dialog asking some questions about the track
- NewTrackDialog dialog(this);
- if (dialog.exec() == QDialog::Accepted)
- {
- const unsigned int cols = dialog.cols();
- const unsigned int rows = dialog.rows();
-
- assert(m_editorData);
-
- m_editorData->setTrackData(TrackDataPtr(new TrackData(dialog.name(), dialog.isUserTrack(), cols, rows)));
-
- delete m_editorScene;
- m_editorScene = new EditorScene;
-
- m_editorView->setScene(m_editorScene);
- m_editorView->updateSceneRect();
-
- // Undo stack has been cleared.
- m_undoAction->setEnabled(false);
- m_redoAction->setEnabled(false);
-
- m_editorData->addTilesToScene();
- m_editorData->addObjectsToScene();
-
- fitScale();
-
- setActionStatesOnNewTrack();
-
- console(QString(tr("A new track '%1' created. Columns: %2, Rows: %3."))
- .arg(m_editorData->trackData()->name())
- .arg(m_editorData->trackData()->map().cols())
- .arg(m_editorData->trackData()->map().rows()));
-
- setTitle(tr("New file"));
+ m_saveAction->setEnabled(true);
- m_clearRouteAction->setEnabled(false);
+ setActionStatesOnNewTrack();
- m_saved = false;
- }
+ m_mediator->setupTrackAfterUndoOrRedo();
- QApplication::restoreOverrideCursor();
+ m_clearRouteAction->setEnabled(m_mediator->routeHasNodes());
}
void MainWindow::setActionStatesOnNewTrack()
@@ -732,114 +704,20 @@
m_saveAction->setEnabled(true);
m_saveAsAction->setEnabled(true);
m_toolBar->setEnabled(true);
- m_enlargeHorSize->setEnabled(true);
- m_enlargeVerSize->setEnabled(true);
m_setRouteAction->setEnabled(true);
m_setTrackPropertiesAction->setEnabled(true);
}
void MainWindow::setTrackProperties()
{
- // Show a dialog to set some properties e.g. lap count.
- assert(m_editorData);
- TrackPropertiesDialog dialog(m_editorData->trackData()->name(), m_editorData->trackData()->index(), m_editorData->trackData()->isUserTrack(), this);
- if (dialog.exec() == QDialog::Accepted)
- {
- m_editorData->trackData()->setName(dialog.name());
- m_editorData->trackData()->setIndex(dialog.index());
- m_editorData->trackData()->setUserTrack(dialog.isUserTrack());
- console(QString(tr("Track properties updated.")));
- }
-}
-
-void MainWindow::enlargeHorSize()
-{
- assert(m_editorData);
- if (m_editorData->trackData())
+ if (m_mediator->setTrackProperties())
{
- m_editorData->trackData()->enlargeHorSize();
- m_editorData->addTilesToScene();
-
- m_editorView->updateSceneRect();
- }
-}
-
-void MainWindow::enlargeVerSize()
-{
- assert(m_editorData);
- if (m_editorData->trackData())
- {
- m_editorData->trackData()->enlargeVerSize();
- m_editorData->addTilesToScene();
-
- m_editorView->updateSceneRect();
- }
-}
-
-void MainWindow::enableUndo(bool enable)
-{
- m_undoAction->setEnabled(enable);
-}
-
-void MainWindow::beginSetRoute()
-{
- QApplication::restoreOverrideCursor();
-
- assert(m_editorData);
-
- m_editorData->saveUndoPoint();
-
- if (m_editorData->canRouteBeSet())
- {
- console(tr("Set route: begin."));
- QMessageBox::information(
- this,
- tr("Set route, checkpoints and driving lines."),
- tr("Setting the route defines checkpoints for the cars so\n"
- "that no shortcuts can be taken. It also defines\n"
- "driving lines for the computer players.\n\n"
- "Click on the tiles one by one and make a closed loop\n"
- "with the target nodes. You can adjust the nodes afterwads.\n"
- "Start from the first tile after the finish line tile\n"
- "to make the lap detection and timing work correctly.\n"
- "Click on the first node again to finish."));
- m_editorData->beginSetRoute();
- }
- else
- {
- QMessageBox::critical(this, tr("Set route"), tr("Invalid track. Route cannot be set."));
- console(tr("Set route: not a valid track."));
+ console(QString(tr("Track properties updated.")));
}
}
-void MainWindow::endSetRoute()
-{
- assert(m_editorData);
- m_editorData->endSetRoute();
- m_clearRouteAction->setEnabled(m_editorData->trackData()->route().numNodes());
- console(tr("Set route: route finished."));
-}
-
-void MainWindow::console(QString text)
-{
- QDateTime date = QDateTime::currentDateTime();
- m_console->append(QString("(") + date.toString("hh:mm:ss") + "): " + text);
-}
-
-void MainWindow::clearEditMode()
-{
- QApplication::restoreOverrideCursor();
- m_editorData->setMode(EditorData::EditorMode::None);
-}
-
-void MainWindow::fitScale()
-{
- m_editorView->centerOn(m_editorView->sceneRect().center());
- m_scaleSlider->setValue(m_editorView->viewport()->height() * 100 / m_editorView->sceneRect().height());
-}
-
MainWindow::~MainWindow()
{
- delete m_editorData;
+ delete m_mediator;
delete m_objectModelLoader;
}
diff -Nuar a/src/editor/mainwindow.hpp b/src/editor/mainwindow.hpp
--- a/src/editor/mainwindow.hpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/mainwindow.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -21,15 +21,14 @@
#include <QString>
class AboutDlg;
-class EditorData;
-class EditorView;
-class EditorScene;
class ObjectModelLoader;
class QAction;
class QCheckBox;
class QSlider;
class QTextEdit;
class QToolBar;
+
+class Mediator;
class TrackData;
/*! \class MainWindow
@@ -59,15 +58,6 @@
//! Print text to the console.
void console(QString text);
- //! Get reference to the view.
- EditorView & editorView() const;
-
- //! Get reference to the scene.
- EditorScene & editorScene() const;
-
- //! Get reference to the data.
- EditorData & editorData() const;
-
//! Get reference to the object loaded.
ObjectModelLoader & objectModelLoader() const;
@@ -89,6 +79,8 @@
void setVisible(bool visible) override;
+ void updateScaleSlider(int value);
+
protected:
void closeEvent(QCloseEvent * event) override;
@@ -99,10 +91,6 @@
bool doOpenTrack(QString fileName);
- void enlargeHorSize();
-
- void enlargeVerSize();
-
void handleToolBarActionClick(QAction * action);
void initializeNewTrack();
@@ -133,6 +121,8 @@
void clearEditMode();
+ void createWidgets();
+
void fitScale();
void init();
@@ -149,12 +139,6 @@
AboutDlg * m_aboutDlg;
- EditorData * m_editorData;
-
- EditorScene * m_editorScene;
-
- EditorView * m_editorView;
-
QTextEdit * m_console;
QAction * m_saveAction = nullptr;
@@ -167,10 +151,6 @@
QAction * m_redoAction = nullptr;
- QAction * m_enlargeHorSize = nullptr;
-
- QAction * m_enlargeVerSize = nullptr;
-
QAction * m_clearRouteAction = nullptr;
QAction * m_setRouteAction = nullptr;
@@ -187,6 +167,18 @@
bool m_saved = false;
+ const char * m_settingsGroup = "MainWindow";
+
+ const unsigned int m_minZoom = 0;
+
+ const unsigned int m_maxZoom = 200;
+
+ const unsigned int m_initZoom = 100;
+
+ const int m_consoleHeight = 64;
+
+ Mediator * m_mediator = nullptr;
+
static MainWindow * m_instance;
};
diff -Nuar a/src/editor/mediator.cpp b/src/editor/mediator.cpp
--- a/src/editor/mediator.cpp 1970-01-01 02:00:00.000000000 +0200
+++ b/src/editor/mediator.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -0,0 +1,475 @@
+// This file is part of Dust Racing 2D.
+// Copyright (C) 2018 Jussi Lind <jussi.lind@iki.fi>
+//
+// Dust Racing 2D is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Dust Racing 2D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
+
+#include "mediator.hpp"
+
+#include "draganddropstore.hpp"
+#include "editordata.hpp"
+#include "editorview.hpp"
+#include "floodfill.hpp"
+#include "mainwindow.hpp"
+#include "newtrackdialog.hpp"
+#include "object.hpp"
+#include "objectfactory.hpp"
+#include "trackdata.hpp"
+#include "tracktile.hpp"
+#include "trackpropertiesdialog.hpp"
+
+#include <cassert>
+
+#include <QApplication>
+#include <QGraphicsScene>
+#include <QLayout>
+#include <QSizePolicy>
+#include <QStatusBar>
+
+Mediator::Mediator(MainWindow & mainWindow)
+ : m_editorData(new EditorData(*this))
+ , m_editorScene(new QGraphicsScene)
+ , m_editorView(new EditorView(*this))
+ , m_mainWindow(mainWindow)
+{
+ m_editorView->setParent(&mainWindow);
+}
+
+void Mediator::addCurrentToolBarObjectToScene(QPointF clickedScenePos)
+{
+ if (QAction * action = MainWindow::instance()->currentToolBarAction())
+ {
+ saveUndoPoint();
+
+ Object & object = ObjectFactory::createObject(action->data().toString());
+ object.setLocation(clickedScenePos);
+
+ if (MainWindow::instance()->randomlyRotateObjects())
+ {
+ object.setRotation(std::rand() % 360);
+ }
+
+ addObject(object);
+ setSelectedObject(&object);
+ }
+}
+
+void Mediator::addItem(QGraphicsItem * item)
+{
+ m_editorScene->addItem(item);
+}
+
+void Mediator::addObject(Object & object)
+{
+ m_editorScene->addItem(&object);
+ m_editorData->trackData()->objects().add(ObjectBasePtr(&object));
+}
+
+void Mediator::addViewToLayout(QLayout * layout)
+{
+ layout->addWidget(m_editorView);
+}
+
+bool Mediator::beginSetRoute()
+{
+ QApplication::restoreOverrideCursor();
+
+ assert(m_editorData);
+
+ m_editorData->saveUndoPoint();
+
+ if (m_editorData->canRouteBeSet())
+ {
+ m_editorData->beginSetRoute();
+
+ return true;
+ }
+
+ return false;
+}
+
+void Mediator::console(QString message)
+{
+ m_mainWindow.console(message);
+}
+
+QString Mediator::currentFileName() const
+{
+ return m_editorData->trackData()->fileName();
+}
+
+QAction * Mediator::currentToolBarAction() const
+{
+ return m_mainWindow.currentToolBarAction();
+}
+
+DragAndDropStore & Mediator::dadStore()
+{
+ return m_editorData->dadStore();
+}
+
+void Mediator::deleteColumn()
+{
+ auto deleted = m_editorData->trackData()->deleteColumn(m_editorData->activeColumn());
+ for (auto && tile : deleted) {
+ m_editorData->removeTileFromScene(tile);
+ }
+}
+
+void Mediator::deleteRow()
+{
+ auto deleted = m_editorData->trackData()->deleteRow(m_editorData->activeRow());
+ for (auto && tile : deleted) {
+ m_editorData->removeTileFromScene(tile);
+ }
+}
+
+void Mediator::floodFill(TrackTile & tile, QAction * action, const QString & typeToFill)
+{
+ saveUndoPoint();
+
+ FloodFill::floodFill(tile, action, typeToFill, m_editorData->trackData()->map());
+}
+
+void Mediator::endSetRoute()
+{
+ setMode(EditorMode::None);
+}
+
+void Mediator::enableUndo(bool enable)
+{
+ m_mainWindow.enableUndo(enable);
+}
+
+int Mediator::fitScale()
+{
+ m_editorView->centerOn(m_editorView->sceneRect().center());
+ return m_editorView->viewport()->height() * 100 / m_editorView->sceneRect().height();
+}
+
+bool Mediator::initializeNewTrack(QString & name, int & cols, int & rows)
+{
+ assert(m_editorData);
+
+ // Show a dialog asking some questions about the track
+ NewTrackDialog dialog(&m_mainWindow);
+ if (dialog.exec() == QDialog::Accepted)
+ {
+ cols = dialog.cols();
+ rows = dialog.rows();
+ name = dialog.name();
+
+ m_editorData->setTrackData(TrackDataPtr(new TrackData(name, dialog.isUserTrack(), cols, rows)));
+
+ delete m_editorScene;
+ m_editorScene = new QGraphicsScene;
+
+ m_editorView->setScene(m_editorScene);
+ m_editorView->updateSceneRect();
+
+ m_editorData->addTilesToScene();
+ m_editorData->addObjectsToScene();
+
+ return true;
+ }
+
+ return false;
+}
+
+void Mediator::insertColumnAfter()
+{
+ m_editorData->trackData()->insertColumn(m_editorData->activeColumn(), MapBase::InsertDirection::After);
+ m_editorData->addTilesToScene();
+}
+
+void Mediator::insertColumnBefore()
+{
+ m_editorData->trackData()->insertColumn(m_editorData->activeColumn(), MapBase::InsertDirection::Before);
+ m_editorData->addTilesToScene();
+}
+
+void Mediator::insertRowAfter()
+{
+ m_editorData->trackData()->insertRow(m_editorData->activeRow(), MapBase::InsertDirection::After);
+ m_editorData->addTilesToScene();
+}
+
+void Mediator::insertRowBefore()
+{
+ m_editorData->trackData()->insertRow(m_editorData->activeRow(), MapBase::InsertDirection::Before);
+ m_editorData->addTilesToScene();
+}
+
+void Mediator::initScene()
+{
+ m_editorView->setScene(m_editorScene);
+ m_editorView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ m_editorView->setMouseTracking(true);
+}
+
+bool Mediator::isUndoable() const
+{
+ return m_editorData->isUndoable();
+}
+
+void Mediator::clearEditMode()
+{
+ QApplication::restoreOverrideCursor();
+ setMode(EditorMode::None);
+}
+
+void Mediator::clearRoute()
+{
+ assert(m_editorData);
+
+ m_editorData->saveUndoPoint();
+ m_editorData->clearRoute();
+}
+
+int Mediator::cols()
+{
+ if (m_editorData->trackData())
+ {
+ return m_editorData->trackData()->map().cols();
+ }
+ return 0;
+}
+
+bool Mediator::openTrack(QString fileName)
+{
+ assert(m_editorData);
+
+ if (m_editorData->loadTrackData(fileName))
+ {
+ delete m_editorScene;
+ m_editorScene = new QGraphicsScene;
+
+ m_editorView->setScene(m_editorScene);
+ m_editorView->updateSceneRect();
+
+ m_editorData->addTilesToScene();
+ m_editorData->addObjectsToScene();
+ m_editorData->addExistingRouteToScene();
+
+ return true;
+ }
+
+ return false;
+}
+
+bool Mediator::isRedoable() const
+{
+ return m_editorData->isRedoable();
+}
+
+void Mediator::mouseWheelZoom(int delta)
+{
+ const int sensitivity = 10;
+ const int currentScale = m_editorData->currentScale();
+ const int maxScale = 200;
+
+ int newScale = currentScale;
+
+ if (delta < 0)
+ {
+ if (currentScale > sensitivity)
+ {
+ newScale = currentScale - sensitivity;
+ }
+ else
+ {
+ newScale = 0;
+ }
+ }
+ else if (delta > 0)
+ {
+ if (currentScale + sensitivity < maxScale)
+ {
+ newScale = currentScale + sensitivity;
+ }
+ else
+ {
+ newScale = maxScale;
+ }
+ }
+
+ if (newScale != currentScale)
+ {
+ setScale(newScale);
+ m_mainWindow.updateScaleSlider(newScale);
+ }
+}
+
+void Mediator::pushNewTargetNodeToRoute(QPointF pos)
+{
+ m_editorData->pushNewTargetNodeToRoute(pos);
+}
+
+void Mediator::redo()
+{
+ m_editorData->redo();
+}
+
+void Mediator::removeItem(QGraphicsItem * item)
+{
+ m_editorScene->removeItem(item);
+}
+
+void Mediator::removeObject(Object & object)
+{
+ m_editorScene->removeItem(&object);
+ m_editorData->trackData()->objects().remove(object);
+}
+
+bool Mediator::routeHasNodes() const
+{
+ return m_editorData->trackData()->route().numNodes();
+}
+
+void Mediator::saveUndoPoint()
+{
+ m_editorData->saveUndoPoint();
+}
+
+bool Mediator::saveTrackData()
+{
+ return m_editorData->saveTrackData();
+}
+
+bool Mediator::saveTrackDataAs(QString fileName)
+{
+ return m_editorData->saveTrackDataAs(fileName);
+}
+
+void Mediator::setMode(EditorMode mode)
+{
+ m_mode = mode;
+}
+
+void Mediator::setSelectedObject(Object * object)
+{
+ m_editorData->setSelectedObject(object);
+}
+
+Object * Mediator::selectedObject() const
+{
+ return m_editorData->selectedObject();
+}
+
+void Mediator::setSelectedTargetNode(TargetNode * tnode)
+{
+ m_editorData->setSelectedTargetNode(tnode);
+}
+
+TargetNode * Mediator::selectedTargetNode() const
+{
+ return m_editorData->selectedTargetNode();
+}
+
+void Mediator::setScale(int value)
+{
+ const qreal scale = static_cast<qreal>(value) / 100;
+ QTransform transform;
+ transform.scale(scale, scale);
+ m_editorView->setTransform(transform);
+ m_editorData->setCurrentScale(value);
+}
+
+EditorMode Mediator::mode() const
+{
+ return m_mode;
+}
+
+int Mediator::rows()
+{
+ if (m_editorData->trackData())
+ {
+ return m_editorData->trackData()->map().rows();
+ }
+ return 0;
+}
+
+bool Mediator::setTrackProperties()
+{
+ assert(m_editorData);
+
+ // Show a dialog to set some properties e.g. lap count.
+ TrackPropertiesDialog dialog(
+ m_editorData->trackData()->name(), m_editorData->trackData()->index(), m_editorData->trackData()->isUserTrack(), &m_mainWindow);
+ if (dialog.exec() == QDialog::Accepted)
+ {
+ m_editorData->trackData()->setName(dialog.name());
+ m_editorData->trackData()->setIndex(dialog.index());
+ m_editorData->trackData()->setUserTrack(dialog.isUserTrack());
+ return true;
+ }
+
+ return false;
+}
+
+void Mediator::showStatusBarMessage(QString message)
+{
+ m_mainWindow.statusBar()->showMessage(message);
+}
+
+void Mediator::setupTrackAfterUndoOrRedo()
+{
+ delete m_editorScene;
+ m_editorScene = new QGraphicsScene;
+
+ m_editorView->setScene(m_editorScene);
+ m_editorView->updateSceneRect();
+
+ m_editorData->addTilesToScene();
+ m_editorData->addObjectsToScene();
+ m_editorData->addExistingRouteToScene();
+}
+
+void Mediator::undo()
+{
+ m_editorData->undo();
+}
+
+void Mediator::updateCoordinates(QPointF mappedPos)
+{
+ if (m_editorData->trackData())
+ {
+ const int maxCols = static_cast<int>(m_editorData->trackData()->map().cols());
+ int column = mappedPos.x() / TrackTile::TILE_W;
+ column = column >= maxCols ? maxCols - 1 : column;
+ column = column < 0 ? 0 : column;
+
+ const int maxRows = static_cast<int>(m_editorData->trackData()->map().rows());
+ int row = mappedPos.y() / TrackTile::TILE_H;
+ row = row >= maxRows ? maxRows - 1 : row;
+ row = row < 0 ? 0 : row;
+
+ m_editorData->setActiveRow(static_cast<unsigned int>(row));
+ m_editorData->setActiveColumn(static_cast<unsigned int>(column));
+
+ QString coordinates("X: %1 Y: %2 I: %3 J: %4");
+ coordinates = coordinates.arg(mappedPos.x()).arg(mappedPos.y()).arg(column).arg(row);
+
+ showStatusBarMessage(coordinates);
+ }
+}
+
+void Mediator::updateView()
+{
+ m_editorView->update();
+}
+
+Mediator::~Mediator()
+{
+ delete m_editorData;
+}
+
diff -Nuar a/src/editor/mediator.hpp b/src/editor/mediator.hpp
--- a/src/editor/mediator.hpp 1970-01-01 02:00:00.000000000 +0200
+++ b/src/editor/mediator.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -0,0 +1,157 @@
+// This file is part of Dust Racing 2D.
+// Copyright (C) 2018 Jussi Lind <jussi.lind@iki.fi>
+//
+// Dust Racing 2D is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Dust Racing 2D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef MEDIATOR_HPP
+#define MEDIATOR_HPP
+
+#include <QString>
+
+#include "editormode.hpp"
+#include "targetnode.hpp"
+
+class DragAndDropStore;
+class EditorData;
+class EditorView;
+class MainWindow;
+class TrackTile;
+class Object;
+class QAction;
+class QGraphicsScene;
+class QLayout;
+
+/*! Acts as a communication channel between MainWindow and editor components:
+ *
+ * - MainWindow <-> Mediator <-> QGraphicsScene / EditorView / EditorData
+ * - EditorView <-> Mediator <-> EditorData
+ */
+class Mediator
+{
+public:
+
+ explicit Mediator(MainWindow & mainWindow);
+
+ ~Mediator();
+
+ void addCurrentToolBarObjectToScene(QPointF clickedScenePos);
+
+ void addItem(QGraphicsItem * item);
+
+ void addObject(Object & object);
+
+ void addViewToLayout(QLayout * layout);
+
+ bool beginSetRoute();
+
+ void clearEditMode();
+
+ void clearRoute();
+
+ int cols();
+
+ void console(QString message);
+
+ QString currentFileName() const;
+
+ QAction * currentToolBarAction() const;
+
+ DragAndDropStore & dadStore();
+
+ void deleteColumn();
+
+ void deleteRow();
+
+ void endSetRoute();
+
+ void enableUndo(bool enable);
+
+ void floodFill(TrackTile & tile, QAction * action, const QString & typeToFill);
+
+ int fitScale();
+
+ void initScene();
+
+ bool initializeNewTrack(QString & name, int & cols, int & rows);
+
+ void insertColumnAfter();
+
+ void insertColumnBefore();
+
+ void insertRowAfter();
+
+ void insertRowBefore();
+
+ bool isUndoable() const;
+
+ bool isRedoable() const;
+
+ void mouseWheelZoom(int delta);
+
+ bool openTrack(QString fileName);
+
+ void pushNewTargetNodeToRoute(QPointF pos);
+
+ void redo();
+
+ void removeItem(QGraphicsItem * item);
+
+ void removeObject(Object & object);
+
+ bool routeHasNodes() const;
+
+ int rows();
+
+ void saveUndoPoint();
+
+ bool saveTrackData();
+
+ bool saveTrackDataAs(QString fileName);
+
+ void setScale(int value);
+
+ void setMode(EditorMode newMode);
+ EditorMode mode() const;
+
+ void setSelectedObject(Object * object);
+ Object * selectedObject() const;
+
+ void setSelectedTargetNode(TargetNode * tnode);
+ TargetNode * selectedTargetNode() const;
+
+ bool setTrackProperties();
+
+ void showStatusBarMessage(QString message);
+
+ void setupTrackAfterUndoOrRedo();
+
+ void undo();
+
+ void updateCoordinates(QPointF mappedPos);
+
+ void updateView();
+
+private:
+
+ EditorData * m_editorData;
+
+ QGraphicsScene * m_editorScene;
+
+ EditorView * m_editorView;
+
+ MainWindow & m_mainWindow;
+
+ EditorMode m_mode = EditorMode::None;
+};
+
+#endif // MEDIATOR_HPP
diff -Nuar a/src/editor/trackdata.cpp b/src/editor/trackdata.cpp
--- a/src/editor/trackdata.cpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/trackdata.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -104,16 +104,6 @@
return m_objects;
}
-void TrackData::enlargeHorSize()
-{
- m_map.resize(m_map.cols() + 1, m_map.rows());
-}
-
-void TrackData::enlargeVerSize()
-{
- m_map.resize(m_map.cols(), m_map.rows() + 1);
-}
-
void TrackData::insertColumn(unsigned int at, MapBase::InsertDirection insertDirection)
{
at = m_map.insertColumn(at, insertDirection);
diff -Nuar a/src/editor/trackdata.hpp b/src/editor/trackdata.hpp
--- a/src/editor/trackdata.hpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/editor/trackdata.hpp 2018-02-11 08:22:08.000000000 +0300
@@ -64,12 +64,6 @@
//! Get objects object.
const Objects & objects() const;
- //! Enlarge horizontal size.
- void enlargeHorSize();
-
- //! Enlarge vertical size.
- void enlargeVerSize();
-
//! Insert tile column at given index and move objects.
void insertColumn(unsigned int at, MapBase::InsertDirection insertDirection);
diff -Nuar a/src/game/renderer.cpp b/src/game/renderer.cpp
--- a/src/game/renderer.cpp 2017-12-30 16:09:21.000000000 +0300
+++ b/src/game/renderer.cpp 2018-02-11 08:22:08.000000000 +0300
@@ -55,7 +55,7 @@
, m_eventHandler(nullptr)
, m_viewAngle(22.5f)
, m_zNear(10.0f)
-, m_zFar(1500.0f)
+, m_zFar(10000.0f) // See: https://github.com/juzzlin/DustRacing2D/issues/30
, m_fadeValue(1.0f)
, m_enabled(false)
, m_hRes(hRes)