462 files added
417 files deleted
72 files renamed
37 files modified
| New file |
| | |
| | | 0: |
| | | {"Width":1350,"Height":901,"Obstacles":[{"Points":[{"X":1,"Y":357},{"X":803,"Y":359},{"X":1029,"Y":406},{"X":1229,"Y":361},{"X":1346,"Y":357},{"X":1346,"Y":1},{"X":0,"Y":3}],"Length":7},{"Points":[{"X":1348,"Y":739},{"X":1254,"Y":735},{"X":1250,"Y":696},{"X":1042,"Y":701},{"X":1042,"Y":726},{"X":252,"Y":735},{"X":243,"Y":680},{"X":1,"Y":700},{"X":1,"Y":900},{"X":1347,"Y":901}],"Length":10}],"LocationPoints":[{"Point":{"X":100,"Y":411},"Parameter":6},{"Point":{"X":591,"Y":410},"Parameter":5},{"Point":{"X":1077,"Y":408},"Parameter":4}],"FindPathPoints":[{"X":1213,"Y":401},{"X":122,"Y":404}],"LoopLines":[{"P1":{"X":122,"Y":404},"P2":{"X":1213,"Y":401}}],"FindPathLines":[],"NextGates":[{"Point":{"X":1197,"Y":402},"Parameter":1}],"PathGuides":[]} |
| | | 1: |
| | | {"Width":1349,"Height":900,"Obstacles":[{"Points":[{"X":124,"Y":324},{"X":760,"Y":310},{"X":956,"Y":414},{"X":1124,"Y":372},{"X":1113,"Y":301},{"X":1346,"Y":297},{"X":1345,"Y":3},{"X":0,"Y":2},{"X":0,"Y":375}],"Length":9},{"Points":[{"X":1342,"Y":675},{"X":1189,"Y":675},{"X":1191,"Y":713},{"X":949,"Y":712},{"X":867,"Y":772},{"X":840,"Y":897},{"X":1345,"Y":899}],"Length":7},{"Points":[{"X":651,"Y":668},{"X":459,"Y":671},{"X":446,"Y":641},{"X":247,"Y":641},{"X":236,"Y":608},{"X":155,"Y":612},{"X":150,"Y":549},{"X":295,"Y":541},{"X":376,"Y":557},{"X":472,"Y":592},{"X":473,"Y":609},{"X":627,"Y":606}],"Length":12},{"Points":[{"X":565,"Y":815},{"X":464,"Y":737},{"X":0,"Y":721},{"X":1,"Y":896},{"X":839,"Y":894},{"X":851,"Y":815}],"Length":6}],"LocationPoints":[{"Point":{"X":270,"Y":462},"Parameter":0},{"Point":{"X":732,"Y":461},"Parameter":1},{"Point":{"X":1192,"Y":461},"Parameter":2},{"Point":{"X":708,"Y":344},"Parameter":8},{"Point":{"X":706,"Y":197},"Parameter":9},{"Point":{"X":706,"Y":53},"Parameter":10}],"FindPathPoints":[{"X":1211,"Y":323},{"X":193,"Y":419},{"X":1251,"Y":446},{"X":746,"Y":498},{"X":769,"Y":657},{"X":111,"Y":660}],"LoopLines":[{"P1":{"X":193,"Y":419},"P2":{"X":1251,"Y":446}}],"FindPathLines":[{"P1":{"X":193,"Y":419},"P2":{"X":746,"Y":498}},{"P1":{"X":746,"Y":498},"P2":{"X":1251,"Y":446}},{"P1":{"X":746,"Y":498},"P2":{"X":769,"Y":657}},{"P1":{"X":769,"Y":657},"P2":{"X":1251,"Y":446}},{"P1":{"X":769,"Y":657},"P2":{"X":193,"Y":419}},{"P1":{"X":1251,"Y":446},"P2":{"X":1211,"Y":323}},{"P1":{"X":769,"Y":657},"P2":{"X":1211,"Y":323}},{"P1":{"X":111,"Y":660},"P2":{"X":193,"Y":419}},{"P1":{"X":111,"Y":660},"P2":{"X":769,"Y":657}}]} |
| | | 3: |
| | | {"Width":1348,"Height":900,"Obstacles":[{"Points":[{"X":0,"Y":313},{"X":927,"Y":295},{"X":963,"Y":334},{"X":1275,"Y":314},{"X":1343,"Y":300},{"X":1343,"Y":2},{"X":1,"Y":1}],"Length":7},{"Points":[{"X":878,"Y":366},{"X":750,"Y":369},{"X":733,"Y":354},{"X":740,"Y":325},{"X":876,"Y":324}],"Length":5},{"Points":[{"X":1345,"Y":551},{"X":1170,"Y":587},{"X":1173,"Y":643},{"X":1275,"Y":713},{"X":1346,"Y":706}],"Length":5},{"Points":[{"X":285,"Y":307},{"X":312,"Y":576},{"X":195,"Y":626},{"X":208,"Y":691},{"X":153,"Y":723},{"X":150,"Y":897},{"X":2,"Y":896},{"X":0,"Y":319}],"Length":8},{"Points":[{"X":156,"Y":752},{"X":369,"Y":714},{"X":793,"Y":734},{"X":932,"Y":822},{"X":1032,"Y":814},{"X":1058,"Y":896},{"X":159,"Y":894}],"Length":7},{"Points":[{"X":1037,"Y":824},{"X":1243,"Y":820},{"X":1229,"Y":748},{"X":1269,"Y":718},{"X":1344,"Y":709},{"X":1345,"Y":896},{"X":1064,"Y":897}],"Length":7}],"LocationPoints":[{"Point":{"X":1108,"Y":329},"Parameter":8},{"Point":{"X":1107,"Y":182},"Parameter":9},{"Point":{"X":1107,"Y":37},"Parameter":10}],"FindPathPoints":[{"X":358,"Y":342},{"X":378,"Y":505},{"X":1270,"Y":415},{"X":1038,"Y":650}],"LoopLines":[{"P1":{"X":358,"Y":342},"P2":{"X":1038,"Y":650}}],"FindPathLines":[{"P1":{"X":358,"Y":342},"P2":{"X":1270,"Y":415}},{"P1":{"X":1270,"Y":415},"P2":{"X":1038,"Y":650}},{"P1":{"X":1270,"Y":415},"P2":{"X":378,"Y":505}},{"P1":{"X":378,"Y":505},"P2":{"X":358,"Y":342}},{"P1":{"X":378,"Y":505},"P2":{"X":1038,"Y":650}}]} |
| | | 6: |
| | | {"Width":1350,"Height":900,"Obstacles":[{"Points":[{"X":325,"Y":425},{"X":437,"Y":447},{"X":567,"Y":437},{"X":565,"Y":395},{"X":631,"Y":398},{"X":675,"Y":410},{"X":809,"Y":405},{"X":810,"Y":375},{"X":933,"Y":329},{"X":1279,"Y":303},{"X":1345,"Y":367},{"X":1345,"Y":5},{"X":1,"Y":6}],"Length":13},{"Points":[{"X":1347,"Y":481},{"X":1246,"Y":501},{"X":1235,"Y":551},{"X":1188,"Y":617},{"X":1192,"Y":669},{"X":1348,"Y":673}],"Length":6},{"Points":[{"X":1349,"Y":701},{"X":791,"Y":719},{"X":803,"Y":659},{"X":396,"Y":665},{"X":361,"Y":723},{"X":2,"Y":711},{"X":0,"Y":896},{"X":1345,"Y":898}],"Length":8}],"LocationPoints":[{"Point":{"X":1080,"Y":425},"Parameter":4},{"Point":{"X":592,"Y":427},"Parameter":5},{"Point":{"X":103,"Y":427},"Parameter":6}],"FindPathPoints":[{"X":174,"Y":537},{"X":1197,"Y":430},{"X":602,"Y":502}],"LoopLines":[{"P1":{"X":174,"Y":537},"P2":{"X":1197,"Y":430}}],"FindPathLines":[{"P1":{"X":174,"Y":537},"P2":{"X":602,"Y":502}},{"P1":{"X":602,"Y":502},"P2":{"X":1197,"Y":430}}]} |
| | | 7: |
| | | {"Width":1350,"Height":900,"Obstacles":[{"Points":[{"X":31,"Y":409},{"X":127,"Y":312},{"X":505,"Y":351},{"X":570,"Y":394},{"X":733,"Y":418},{"X":888,"Y":410},{"X":896,"Y":334},{"X":1066,"Y":328},{"X":1100,"Y":401},{"X":1315,"Y":425},{"X":1349,"Y":427},{"X":1343,"Y":1},{"X":4,"Y":4},{"X":1,"Y":341}],"Length":14},{"Points":[{"X":467,"Y":896},{"X":472,"Y":733},{"X":325,"Y":676},{"X":178,"Y":636},{"X":0,"Y":625},{"X":2,"Y":900}],"Length":6}],"LocationPoints":[{"Point":{"X":270,"Y":462},"Parameter":0},{"Point":{"X":730,"Y":463},"Parameter":1},{"Point":{"X":1191,"Y":463},"Parameter":2},{"Point":{"X":1078,"Y":499},"Parameter":4},{"Point":{"X":589,"Y":497},"Parameter":5},{"Point":{"X":100,"Y":498},"Parameter":6}],"FindPathPoints":[{"X":146,"Y":440},{"X":1226,"Y":720}],"LoopLines":[{"P1":{"X":146,"Y":440},"P2":{"X":1226,"Y":720}}],"FindPathLines":[]} |
| | | 8: |
| | | {"Width":1686,"Height":720,"Obstacles":[{"Points":[{"X":2,"Y":420},{"X":130,"Y":439},{"X":311,"Y":462},{"X":313,"Y":400},{"X":221,"Y":319},{"X":453,"Y":288},{"X":632,"Y":5},{"X":4,"Y":2}],"Length":8},{"Points":[{"X":574,"Y":104},{"X":743,"Y":319},{"X":961,"Y":306},{"X":1014,"Y":343},{"X":1099,"Y":326},{"X":1165,"Y":369},{"X":1534,"Y":365},{"X":1684,"Y":309},{"X":1680,"Y":4},{"X":633,"Y":5}],"Length":10},{"Points":[{"X":1682,"Y":470},{"X":1540,"Y":514},{"X":1442,"Y":590},{"X":1173,"Y":641},{"X":858,"Y":670},{"X":814,"Y":708},{"X":1681,"Y":715}],"Length":7}],"LocationPoints":[{"Point":{"X":277,"Y":501},"Parameter":0},{"Point":{"X":735,"Y":502},"Parameter":1},{"Point":{"X":1196,"Y":502},"Parameter":2},{"Point":{"X":1418,"Y":390},"Parameter":4},{"Point":{"X":930,"Y":387},"Parameter":5},{"Point":{"X":441,"Y":388},"Parameter":6}],"FindPathPoints":[{"X":186,"Y":483},{"X":1565,"Y":393},{"X":549,"Y":448}],"LoopLines":[{"P1":{"X":186,"Y":483},"P2":{"X":1565,"Y":393}}],"FindPathLines":[{"P1":{"X":186,"Y":483},"P2":{"X":549,"Y":448}},{"P1":{"X":549,"Y":448},"P2":{"X":1565,"Y":393}}]} |
| | | 9: |
| | | {"Width":1688,"Height":720,"Obstacles":[{"Points":[{"X":3,"Y":333},{"X":390,"Y":305},{"X":600,"Y":389},{"X":746,"Y":389},{"X":766,"Y":327},{"X":890,"Y":334},{"X":914,"Y":247},{"X":1092,"Y":225},{"X":1305,"Y":396},{"X":1489,"Y":346},{"X":1684,"Y":411},{"X":1683,"Y":3},{"X":3,"Y":3}],"Length":13},{"Points":[{"X":389,"Y":671},{"X":398,"Y":614},{"X":868,"Y":605},{"X":1037,"Y":631},{"X":1125,"Y":589},{"X":1536,"Y":632},{"X":1678,"Y":682},{"X":1682,"Y":715},{"X":378,"Y":715}],"Length":9}],"LocationPoints":[{"Point":{"X":274,"Y":500},"Parameter":0},{"Point":{"X":738,"Y":502},"Parameter":1},{"Point":{"X":1200,"Y":501},"Parameter":2},{"Point":{"X":1658,"Y":503},"Parameter":3}],"FindPathPoints":[{"X":216,"Y":456},{"X":1545,"Y":466},{"X":985,"Y":515}],"LoopLines":[{"P1":{"X":216,"Y":456},"P2":{"X":1545,"Y":466}}],"FindPathLines":[{"P1":{"X":216,"Y":456},"P2":{"X":985,"Y":515}},{"P1":{"X":985,"Y":515},"P2":{"X":1545,"Y":466}}]} |
| | | 11: |
| | | {"Width":1686,"Height":720,"Obstacles":[{"Points":[{"X":1678,"Y":410},{"X":1576,"Y":341},{"X":1258,"Y":344},{"X":1241,"Y":379},{"X":1153,"Y":380},{"X":849,"Y":377},{"X":765,"Y":353},{"X":598,"Y":352},{"X":498,"Y":387},{"X":0,"Y":360},{"X":1,"Y":1},{"X":1681,"Y":2}],"Length":12},{"Points":[{"X":1566,"Y":714},{"X":1502,"Y":662},{"X":875,"Y":654},{"X":780,"Y":660},{"X":550,"Y":636},{"X":365,"Y":614},{"X":183,"Y":626},{"X":72,"Y":636},{"X":10,"Y":655},{"X":0,"Y":715}],"Length":10}],"LocationPoints":[{"Point":{"X":929,"Y":450},"Parameter":5},{"Point":{"X":440,"Y":452},"Parameter":6},{"Point":{"X":1416,"Y":451},"Parameter":4}],"FindPathPoints":[{"X":71,"Y":469},{"X":1529,"Y":462},{"X":826,"Y":576}],"LoopLines":[{"P1":{"X":71,"Y":469},"P2":{"X":1529,"Y":462}}],"FindPathLines":[{"P1":{"X":71,"Y":469},"P2":{"X":826,"Y":576}},{"P1":{"X":826,"Y":576},"P2":{"X":1529,"Y":462}}]} |
| | | 12: |
| | | {"Width":2024,"Height":720,"Obstacles":[{"Points":[{"X":795,"Y":351},{"X":1897,"Y":323},{"X":2019,"Y":271},{"X":2019,"Y":4},{"X":1,"Y":2},{"X":3,"Y":347},{"X":111,"Y":400},{"X":200,"Y":377},{"X":294,"Y":344},{"X":560,"Y":351},{"X":623,"Y":381}],"Length":11},{"Points":[{"X":2020,"Y":614},{"X":1464,"Y":615},{"X":1137,"Y":589},{"X":895,"Y":606},{"X":855,"Y":715},{"X":2020,"Y":716}],"Length":6},{"Points":[{"X":525,"Y":715},{"X":451,"Y":589},{"X":156,"Y":603},{"X":2,"Y":495},{"X":2,"Y":716}],"Length":5}],"LocationPoints":[{"Point":{"X":270,"Y":461},"Parameter":0},{"Point":{"X":731,"Y":461},"Parameter":1},{"Point":{"X":1192,"Y":462},"Parameter":2},{"Point":{"X":1650,"Y":463},"Parameter":3},{"Point":{"X":1278,"Y":347},"Parameter":5},{"Point":{"X":788,"Y":347},"Parameter":6},{"Point":{"X":301,"Y":346},"Parameter":7},{"Point":{"X":628,"Y":175},"Parameter":8},{"Point":{"X":627,"Y":28},"Parameter":9}],"FindPathPoints":[{"X":201,"Y":457},{"X":1894,"Y":423},{"X":699,"Y":513}],"LoopLines":[{"P1":{"X":201,"Y":457},"P2":{"X":1894,"Y":423}}],"FindPathLines":[{"P1":{"X":201,"Y":457},"P2":{"X":699,"Y":513}},{"P1":{"X":699,"Y":513},"P2":{"X":1894,"Y":423}}]} |
| | | 13: |
| | | {"Width":2024,"Height":900,"Obstacles":[{"Points":[{"X":1607,"Y":189},{"X":1761,"Y":360},{"X":2022,"Y":405},{"X":2022,"Y":1},{"X":1565,"Y":1}],"Length":5},{"Points":[{"X":1350,"Y":400},{"X":1605,"Y":186},{"X":1562,"Y":1},{"X":121,"Y":1},{"X":335,"Y":410},{"X":385,"Y":402}],"Length":6},{"Points":[{"X":2017,"Y":719},{"X":1228,"Y":729},{"X":1137,"Y":666},{"X":667,"Y":689},{"X":417,"Y":671},{"X":123,"Y":649},{"X":121,"Y":891},{"X":2020,"Y":896}],"Length":8},{"Points":[{"X":294,"Y":564},{"X":121,"Y":566},{"X":122,"Y":19},{"X":322,"Y":394},{"X":233,"Y":457}],"Length":5},{"Points":[{"X":1,"Y":2},{"X":127,"Y":3},{"X":128,"Y":896},{"X":0,"Y":894}],"Length":4}],"LocationPoints":[{"Point":{"X":537,"Y":496},"Parameter":0},{"Point":{"X":997,"Y":497},"Parameter":1},{"Point":{"X":1458,"Y":497},"Parameter":2},{"Point":{"X":1918,"Y":496},"Parameter":3},{"Point":{"X":777,"Y":484},"Parameter":6},{"Point":{"X":1266,"Y":484},"Parameter":5},{"Point":{"X":1753,"Y":485},"Parameter":4}],"FindPathPoints":[{"X":425,"Y":495},{"X":1885,"Y":496},{"X":1294,"Y":541}],"LoopLines":[{"P1":{"X":425,"Y":495},"P2":{"X":1885,"Y":496}}],"FindPathLines":[{"P1":{"X":425,"Y":495},"P2":{"X":1294,"Y":541}},{"P1":{"X":1294,"Y":541},"P2":{"X":1885,"Y":496}}]} |
| | | 14: |
| | | {"Width":1687,"Height":901,"Obstacles":[{"Points":[{"X":98,"Y":310},{"X":408,"Y":314},{"X":418,"Y":425},{"X":530,"Y":416},{"X":593,"Y":451},{"X":721,"Y":452},{"X":762,"Y":449},{"X":783,"Y":337},{"X":840,"Y":302},{"X":1207,"Y":300},{"X":1239,"Y":321},{"X":1418,"Y":320},{"X":1584,"Y":378},{"X":1679,"Y":377},{"X":1681,"Y":4},{"X":4,"Y":4},{"X":0,"Y":436}],"Length":17},{"Points":[{"X":1681,"Y":717},{"X":1319,"Y":706},{"X":1165,"Y":653},{"X":1053,"Y":654},{"X":835,"Y":609},{"X":732,"Y":624},{"X":680,"Y":667},{"X":0,"Y":650},{"X":0,"Y":898},{"X":1682,"Y":898}],"Length":10}],"LocationPoints":[{"Point":{"X":278,"Y":481},"Parameter":0},{"Point":{"X":739,"Y":481},"Parameter":1},{"Point":{"X":1200,"Y":479},"Parameter":2},{"Point":{"X":1656,"Y":480},"Parameter":3}],"FindPathPoints":[{"X":140,"Y":474},{"X":1453,"Y":466},{"X":763,"Y":520},{"X":373,"Y":565}],"LoopLines":[{"P1":{"X":140,"Y":474},"P2":{"X":1453,"Y":466}}],"FindPathLines":[{"P1":{"X":140,"Y":474},"P2":{"X":373,"Y":565}},{"P1":{"X":140,"Y":474},"P2":{"X":763,"Y":520}},{"P1":{"X":373,"Y":565},"P2":{"X":763,"Y":520}},{"P1":{"X":763,"Y":520},"P2":{"X":1453,"Y":466}},{"P1":{"X":373,"Y":565},"P2":{"X":1453,"Y":466}}]} |
| | | 16: |
| | | {"Width":1687,"Height":901,"Obstacles":[{"Points":[{"X":3,"Y":385},{"X":257,"Y":388},{"X":655,"Y":320},{"X":711,"Y":264},{"X":1682,"Y":279},{"X":1682,"Y":1},{"X":0,"Y":4}],"Length":7},{"Points":[{"X":5,"Y":713},{"X":265,"Y":754},{"X":432,"Y":862},{"X":405,"Y":900},{"X":1,"Y":896}],"Length":5},{"Points":[{"X":720,"Y":883},{"X":825,"Y":776},{"X":1034,"Y":851},{"X":985,"Y":900},{"X":712,"Y":900}],"Length":5},{"Points":[{"X":1173,"Y":871},{"X":1569,"Y":644},{"X":1674,"Y":661},{"X":1684,"Y":772},{"X":1679,"Y":887},{"X":1187,"Y":893},{"X":1200,"Y":852}],"Length":7}],"LocationPoints":[{"Point":{"X":1391,"Y":410},"Parameter":4},{"Point":{"X":905,"Y":409},"Parameter":5},{"Point":{"X":416,"Y":410},"Parameter":6}],"FindPathPoints":[{"X":633,"Y":693},{"X":1494,"Y":434},{"X":139,"Y":505},{"X":834,"Y":367}],"LoopLines":[{"P1":{"X":139,"Y":505},"P2":{"X":1494,"Y":434}}],"FindPathLines":[{"P1":{"X":139,"Y":505},"P2":{"X":834,"Y":367}},{"P1":{"X":834,"Y":367},"P2":{"X":1494,"Y":434}},{"P1":{"X":633,"Y":693},"P2":{"X":1494,"Y":434}},{"P1":{"X":633,"Y":693},"P2":{"X":834,"Y":367}},{"P1":{"X":633,"Y":693},"P2":{"X":139,"Y":505}}]} |
| | | 17: |
| | | {"Width":1687,"Height":720,"Obstacles":[{"Points":[{"X":1681,"Y":368},{"X":1591,"Y":363},{"X":1487,"Y":252},{"X":1475,"Y":4},{"X":1683,"Y":3}],"Length":5},{"Points":[{"X":1348,"Y":358},{"X":544,"Y":345},{"X":534,"Y":453},{"X":115,"Y":450},{"X":0,"Y":390},{"X":0,"Y":3},{"X":1480,"Y":3},{"X":1487,"Y":245}],"Length":8},{"Points":[{"X":108,"Y":685},{"X":76,"Y":720},{"X":1682,"Y":718},{"X":1684,"Y":683}],"Length":4}],"LocationPoints":[{"Point":{"X":276,"Y":499},"Parameter":0},{"Point":{"X":736,"Y":502},"Parameter":1},{"Point":{"X":1198,"Y":500},"Parameter":2},{"Point":{"X":1655,"Y":502},"Parameter":3}],"FindPathPoints":[{"X":196,"Y":514},{"X":1622,"Y":491},{"X":605,"Y":518}],"LoopLines":[{"P1":{"X":196,"Y":514},"P2":{"X":1622,"Y":491}}],"FindPathLines":[{"P1":{"X":196,"Y":514},"P2":{"X":605,"Y":518}},{"P1":{"X":605,"Y":518},"P2":{"X":1622,"Y":491}}]} |
| | | |
| New file |
| | |
| | | 0: |
| | | {"Width":896,"Height":686,"Obstacles":[{"Points":[{"X":2,"Y":320},{"X":460,"Y":310},{"X":493,"Y":319},{"X":556,"Y":334},{"X":668,"Y":344},{"X":759,"Y":330},{"X":873,"Y":308},{"X":893,"Y":300},{"X":891,"Y":1},{"X":2,"Y":3}],"Length":10},{"Points":[{"X":2,"Y":552},{"X":71,"Y":545},{"X":76,"Y":427},{"X":165,"Y":439},{"X":166,"Y":521},{"X":253,"Y":559},{"X":703,"Y":550},{"X":703,"Y":521},{"X":823,"Y":513},{"X":834,"Y":568},{"X":893,"Y":559},{"X":893,"Y":684},{"X":4,"Y":683}],"Length":13}],"LocationPoints":[{"Point":{"X":797,"Y":348},"Parameter":0},{"Point":{"X":671,"Y":348},"Parameter":1},{"Point":{"X":547,"Y":348},"Parameter":2},{"Point":{"X":423,"Y":348},"Parameter":3},{"Point":{"X":298,"Y":347},"Parameter":4},{"Point":{"X":172,"Y":348},"Parameter":5},{"Point":{"X":47,"Y":348},"Parameter":6}],"FindPathPoints":[{"X":51,"Y":392},{"X":438,"Y":418},{"X":775,"Y":400}],"LoopPoint":{"X":0,"Y":0},"FindPathLines":[{"P1":{"X":51,"Y":392},"P2":{"X":775,"Y":400}},{"P1":{"X":438,"Y":418},"P2":{"X":775,"Y":400}},{"P1":{"X":438,"Y":418},"P2":{"X":51,"Y":392}}],"NextGates":[{"Point":{"X":778,"Y":346},"Parameter":1}],"PathGuides":[{"Polygon":{"Points":[{"X":47,"Y":509},{"X":121,"Y":508},{"X":118,"Y":541},{"X":42,"Y":547}],"Length":4},"Target":{"X":20,"Y":508}}]} |
| | |
| | | rgb 0 ff ff |
| | | hsv 0.5 1 1 |
| | | |
| | | 牛 rgb 255 0 0 |
| | | rgb ff 00 00 |
| | | hsv 0 1 1 |
| | | |
| | | 人 rgb 0 0 255 |
| | | rgb 0 0 ff |
| | | hsv 0.6667 1.00 1.00 |
| | | |
| | | gate_up rgb 255 153 0 |
| | | rgb ff 99 00 |
| | | hsv 0.1 1 1 |
| New file |
| | |
| | | 使用的数字 |
| | | 左0-9 |
| | | 右10-19 |
| | | 上20-29 |
| | | 下30-39 |
| | |
| | | <MenuItem Header="查找方框" Click="FindRectangle" /> |
| | | <MenuItem Header="查找加百利" Click="FindJiaBaili" /> |
| | | |
| | | <MenuItem Header="查找定位点" Click="FindLocationPoint_Click" /> |
| | | |
| | | |
| | | |
| | | <Separator/> |
| | | <MenuItem Header="测试找线" Click="FindLines" /> |
| | | <Separator/> |
| | | <MenuItem Header="查找定位点" Click="FindLocationPoint_Click" /> |
| | | |
| | | |
| | | </MenuItem> |
| | | <MenuItem Header="工具(T)"> |
| | |
| | | using Orientation = RichCreator.Utility.Structs.Orientation; |
| | | using ZTImage.Collections; |
| | | |
| | | |
| | | namespace RichCreator.Editor |
| | | { |
| | | /// <summary> |
| | |
| | | string imagePath = string.Empty; |
| | | Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); |
| | | ofd.DefaultExt = ".jpg"; |
| | | ofd.Filter = "jpg file|*.jpg"; |
| | | ofd.Filter = "jpg file|*.jpg;*.png"; |
| | | ofd.Multiselect = false; |
| | | if (ofd.ShowDialog() == true) |
| | | { |
| | |
| | | /// <param name="e"></param> |
| | | private void FindLocationPoint_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(this.targetImage.Width, this.targetImage.Height); |
| | | CvInvoke.CvtColor(this.targetImage, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | |
| | | MultiList<ZTRectangle, Int32> list = new MultiList<ZTRectangle, int>(); |
| | | ZTRectangle limit = new ZTRectangle(0, 0, this.targetImage.Width, this.targetImage.Height); |
| | | if (DnfCVHelper.GetLocationPoint(out list,hsvImage,limit)) |
| | | ParametersPoint location = DnfCVHelper.GetLocationPoint(this.targetImage, limit); |
| | | if (!location.Equals(ParametersPoint.Empty)) |
| | | { |
| | | //找到位置显示出来 |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | ZTRectangle rect = list[i].Item1; |
| | | Int32 number = list[i].Item2; |
| | | DrawRectangle(rect.Start.X, rect.Start.Y, rect.End.X - rect.Start.X, rect.End.Y - rect.Start.Y, Colors.Green,number); |
| | | } |
| | | |
| | | DrawRectangle(location.Point.X, location.Point.Y, 12, 10, Colors.Green, location.Parameter); |
| | | } |
| | | else |
| | | { |
| | | MessageBox.Show("未找到定位点"); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | window.ShowDialog(); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,4,0,0"> |
| | | |
| | | <TextBlock Text="参数:" Margin="22 0 0 0" VerticalAlignment="Center" /> |
| | | <TextBox Width="45" x:Name="tagNumber" Text="0" VerticalContentAlignment="Center"/> |
| | | <TextBox Width="100" x:Name="tagParameter" Text="0" VerticalContentAlignment="Center"/> |
| | | |
| | | <ComboBox SelectedIndex="0" x:Name="slOperate"> |
| | | <ComboBoxItem>障碍</ComboBoxItem> |
| | | <ComboBoxItem>定位点</ComboBoxItem> |
| | | <ComboBoxItem>寻路点</ComboBoxItem> |
| | | <ComboBoxItem>巡逻线</ComboBoxItem> |
| | | <ComboBoxItem>寻路线</ComboBoxItem> |
| | | <ComboBoxItem>测试起终点 </ComboBoxItem> |
| | | <ComboBoxItem>巡逻点</ComboBoxItem> |
| | | <ComboBoxItem>入门点</ComboBoxItem> |
| | | <ComboBoxItem>路径引导</ComboBoxItem> |
| | | <ComboBoxItem>读坐标</ComboBoxItem> |
| | | <ComboBoxItem>测试起终点</ComboBoxItem> |
| | | </ComboBox> |
| | | <Button Content="清空定位点" Margin="5 0" Click="ClearPosition_Click" /> |
| | | <TextBlock VerticalAlignment="Center">除定位点外,其它物体右键删除。</TextBlock> |
| | |
| | | <Button Content="加载图片" Margin="5 0" Click="OpenFromFile_Click" /> |
| | | <Button Content="复制为JSON" Margin="5 0" Click="CopyJSON_Click" /> |
| | | <Button Content="加载JSON" Margin="5 0" Click="CreateFromJSON_Click" /> |
| | | |
| | | |
| | | <Button Content="生成定位图片" Margin="5 0" Click="CreateLocationPicture" /> |
| | | </StackPanel> |
| | | |
| | | </Grid> |
| | |
| | | <Canvas x:Name="HouseInfoLayer" /> |
| | | <Canvas x:Name="LocationPointLayer" IsHitTestVisible="False"/> |
| | | <Canvas x:Name="StartEndPointLayer" IsHitTestVisible="False"/> |
| | | |
| | | <!--<Polyline StrokeThickness="1" Stroke="Black" Opacity="0.5"> |
| | | <Polyline.Points>10,50 180,50 180,150 </Polyline.Points> |
| | | </Polyline>--> |
| | | <Canvas x:Name="PathGuideLayer" IsHitTestVisible="False"/> |
| | | <Canvas x:Name="PathGuideShapeLayer" /> |
| | | </Canvas> |
| | | </ScrollViewer> |
| | | </Grid> |
| | |
| | | using Emgu.CV; |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.PathFinding; |
| | | using RichCreator.Utility.PathFindings; |
| | | using RichCreator.Utility.Structs; |
| | |
| | | //加载障碍物 |
| | | for (int i = 0; i < info.Obstacles.Count; i++) |
| | | { |
| | | Polygon polygon=CreateObstacleUI(info.Obstacles[i]); |
| | | Polygon polygon = CreateObstacleUI(info.Obstacles[i]); |
| | | this.HouseInfoLayer.Children.Add(polygon); |
| | | } |
| | | |
| | |
| | | this.HouseInfoLayer.Children.Add(fp); |
| | | } |
| | | |
| | | //加载巡逻线 |
| | | for (int i = 0; i < info.LoopLines.Count; i++) |
| | | { |
| | | Line llline = CreateLoopLineUI(info.LoopLines[i]); |
| | | this.HouseInfoLayer.Children.Add(llline); |
| | | } |
| | | |
| | | |
| | | //加载寻路线 |
| | | for (int i = 0; i < info.FindPathLines.Count; i++) |
| | | { |
| | | Line fpline = CreateFindPathLineUI(info.FindPathLines[i]); |
| | | this.HouseInfoLayer.Children.Add(fpline); |
| | | } |
| | | |
| | | |
| | | //加载巡逻点 |
| | | if (!info.LoopPoint.Equals(ZTPoint.Empty)) |
| | | { |
| | | Canvas llline = CreateLoopPointUI(info.LoopPoint); |
| | | this.HouseInfoLayer.Children.Add(llline); |
| | | } |
| | | |
| | | |
| | | //进门点 |
| | | for (int i = 0; i < info.NextGates.Count; i++) |
| | | { |
| | | Canvas ng = CreateNextGateUI(info.NextGates[i]); |
| | | this.HouseInfoLayer.Children.Add(ng); |
| | | } |
| | | |
| | | |
| | | //加载导引区域 |
| | | for (int i = 0; i < info.PathGuides.Count; i++) |
| | | { |
| | | Polygon pg = CreatePathGuideUI(info.PathGuides[i]); |
| | | this.PathGuideShapeLayer.Children.Add(pg); |
| | | } |
| | | |
| | | |
| | | |
| | | this.housePathInfo = info; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 生成定位图片 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void CreateLocationPicture(object sender, RoutedEventArgs e) |
| | | { |
| | | |
| | | string dir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "numbers"); |
| | | if (!System.IO.Directory.Exists(dir)) |
| | | { |
| | | System.IO.Directory.CreateDirectory(dir); |
| | | } |
| | | |
| | | for (Int32 i = 0; i <= 255; i++) |
| | | { |
| | | byte number = (byte)i; |
| | | System.Drawing.Bitmap image = new System.Drawing.Bitmap(12, 10); |
| | | //1 |
| | | SetImagePixel(0, 0, 2, 2, image, System.Drawing.Color.White); |
| | | SetImagePixel(2, 0, 3, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(5, 0, 2, 2, image, System.Drawing.Color.White); |
| | | SetImagePixel(7, 0, 3, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(10, 0, 2, 2, image, System.Drawing.Color.White); |
| | | |
| | | //2 |
| | | SetImagePixel(0, 2, 2, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(10, 2, 2, 2, image, System.Drawing.Color.Black); |
| | | |
| | | //3 |
| | | SetImagePixel(0, 4, 2, 2, image, System.Drawing.Color.White); |
| | | SetImagePixel(2, 4, 3, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(5, 4, 2, 2, image, System.Drawing.Color.White); |
| | | SetImagePixel(7, 4, 3, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(10, 4, 2, 2, image, System.Drawing.Color.White); |
| | | |
| | | //4 |
| | | SetImagePixel(0, 6, 2, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(10, 6, 2, 2, image, System.Drawing.Color.Black); |
| | | |
| | | //5 |
| | | SetImagePixel(0, 8, 2, 2, image, System.Drawing.Color.White); |
| | | SetImagePixel(2, 8, 3, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(5, 8, 2, 2, image, System.Drawing.Color.White); |
| | | SetImagePixel(7, 8, 3, 2, image, System.Drawing.Color.Black); |
| | | SetImagePixel(10, 8, 2, 2, image, System.Drawing.Color.White); |
| | | Int32 x = 0, y = 0; |
| | | for (int bit = 0; bit <= 7; bit++) |
| | | { |
| | | GetBitCoordinate(out x, out y, bit); |
| | | if (HasValueInBit(number, bit)) |
| | | { |
| | | SetImagePixel(x, y, 2, 2, image, System.Drawing.Color.White); |
| | | } |
| | | else |
| | | { |
| | | SetImagePixel(x, y, 2, 2, image, System.Drawing.Color.Black); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | string saveDir = System.IO.Path.Combine(dir, number.ToString() + ".png"); |
| | | image.Save(saveDir, System.Drawing.Imaging.ImageFormat.Png); |
| | | } |
| | | MessageBox.Show("数字文件生成成功,生成至程序目录:numbers目录下"); |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置像素 |
| | | /// </summary> |
| | | /// <param name="x"></param> |
| | | /// <param name="y"></param> |
| | | /// <param name="width"></param> |
| | | /// <param name="height"></param> |
| | | /// <param name="image"></param> |
| | | /// <param name="color"></param> |
| | | private void SetImagePixel(Int32 x, Int32 y, Int32 width, Int32 height, System.Drawing.Bitmap image, System.Drawing.Color color) |
| | | { |
| | | for (int w = 0; w < width; w++) |
| | | { |
| | | for (Int32 h = 0; h < height; h++) |
| | | { |
| | | image.SetPixel(x + w, y + h, color); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 得到指定位坐标 |
| | | /// </summary> |
| | | /// <param name="x"></param> |
| | | /// <param name="y"></param> |
| | | /// <param name="bitIndex"></param> |
| | | private void GetBitCoordinate(out Int32 x, out Int32 y, Int32 bitIndex) |
| | | { |
| | | x = 0; |
| | | y = 0; |
| | | switch (bitIndex) |
| | | { |
| | | case 0: |
| | | x = 8; |
| | | y = 6; |
| | | break; |
| | | case 1: |
| | | x = 6; |
| | | y = 6; |
| | | break; |
| | | case 2: |
| | | x = 4; |
| | | y = 6; |
| | | break; |
| | | case 3: |
| | | x = 2; |
| | | y = 6; |
| | | break; |
| | | case 4: |
| | | x = 8; |
| | | y = 2; |
| | | break; |
| | | case 5: |
| | | x = 6; |
| | | y = 2; |
| | | break; |
| | | case 6: |
| | | x = 4; |
| | | y = 2; |
| | | break; |
| | | case 7: |
| | | x = 2; |
| | | y = 2; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 得到数字指定位是否有值 |
| | | /// </summary> |
| | | /// <param name="number"></param> |
| | | /// <param name="bit"></param> |
| | | /// <returns></returns> |
| | | private bool HasValueInBit(byte number, Int32 bit) |
| | | { |
| | | switch (bit) |
| | | { |
| | | case 0: |
| | | return (number & 0b00000001) != 0; |
| | | case 1: |
| | | return (number & 0b00000010) != 0; |
| | | case 2: |
| | | return (number & 0b00000100) != 0; |
| | | case 3: |
| | | return (number & 0b00001000) != 0; |
| | | case 4: |
| | | return (number & 0b00010000) != 0; |
| | | case 5: |
| | | return (number & 0b00100000) != 0; |
| | | case 6: |
| | | return (number & 0b01000000) != 0; |
| | | case 7: |
| | | return (number & 0b10000000) != 0; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 清理定位点 |
| | |
| | | ZTPoint start = this.startEndFindPathPoint[0]; |
| | | ZTPoint end = this.startEndFindPathPoint[1]; |
| | | |
| | | DNFPathFinding finder = new DNFPathFinding(this.housePathInfo); |
| | | HouseInfo house = new HouseInfo(this.housePathInfo); |
| | | List<ZTPoint> path = house.FindPath(ref start, ref end); |
| | | |
| | | |
| | | List<ZTPoint> path=finder.FindPath(ref start, ref end); |
| | | |
| | | if (path==null||path.Count <= 0) |
| | | if (path == null || path.Count <= 0) |
| | | { |
| | | MessageBox.Show("不用寻路"); |
| | | return; |
| | |
| | | for (int i = 0; i < path.Count; i++) |
| | | { |
| | | |
| | | Line line=GetPathLineUI(lastPoint, path[i]); |
| | | Line line = GetPathLineUI(lastPoint, path[i]); |
| | | this.StartEndPointLayer.Children.Add(line); |
| | | lastPoint = path[i]; |
| | | } |
| | |
| | | } |
| | | //是否添加障碍物 |
| | | OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); |
| | | Int32 number = TypeConverter.StringToInt(this.tagNumber.Text, 0); |
| | | Int32 numParameter = TypeConverter.StringToInt(this.tagParameter.Text, 0); |
| | | string strParameter = this.tagParameter.Text; |
| | | |
| | | if (e.LeftButton == MouseButtonState.Released) |
| | | { |
| | |
| | | Point point = GetPosition(e); |
| | | |
| | | |
| | | if (op == OperateActionD.Obstacle) |
| | | { |
| | | //障碍物 |
| | | |
| | | } |
| | | else if (op == OperateActionD.LocationPoint) |
| | | if (op == OperateActionD.LocationPoint) |
| | | { |
| | | //定位点 |
| | | ParametersPoint lp = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), number); |
| | | ParametersPoint lp = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), numParameter); |
| | | if (this.housePathInfo.AddLocationPosition(lp)) |
| | | { |
| | | Canvas lpControl = CreateLocationPointUI(lp); |
| | |
| | | this.HouseInfoLayer.Children.Add(fpControl); |
| | | } |
| | | } |
| | | else if (op == OperateActionD.LoopLine) |
| | | { |
| | | //循环线 |
| | | ZTPoint llPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); |
| | | if (!llPoint.Equals(ZTPoint.Empty)) |
| | | { |
| | | tempLine = CreateTempLoopLineUI(llPoint); |
| | | this.HouseInfoLayer.Children.Add(tempLine); |
| | | moveable = true; |
| | | } |
| | | } |
| | | else if (op == OperateActionD.FindPathLine) |
| | | { |
| | | //寻路线 |
| | |
| | | moveable = true; |
| | | } |
| | | } |
| | | else if (op == OperateActionD.LoopPoint) |
| | | { |
| | | //循环点 |
| | | if (!this.housePathInfo.LoopPoint.Equals(ZTPoint.Empty)) |
| | | { |
| | | //删除原来的巡逻点 |
| | | } |
| | | |
| | | ZTPoint sepoint = new ZTPoint((Int32)point.X, (Int32)point.Y); |
| | | this.housePathInfo.LoopPoint = sepoint; |
| | | Canvas lp = CreateLoopPointUI(sepoint); |
| | | this.HouseInfoLayer.Children.Add(lp); |
| | | } |
| | | else if (op == OperateActionD.StartEndPoint) |
| | | { |
| | | //画寻路起始和终点 |
| | |
| | | this.StartEndPointLayer.Children.Add(lseControl); |
| | | this.startEndFindPathPoint.Add(sepoint); |
| | | } |
| | | else if (op == OperateActionD.ReadCoordinate) |
| | | { |
| | | //读取坐标 |
| | | ZTPoint sepoint = new ZTPoint((Int32)point.X, (Int32)point.Y); |
| | | this.tagParameter.Text = sepoint.X.ToString() + "," + sepoint.Y.ToString(); |
| | | } |
| | | else if (op == OperateActionD.NextGate) |
| | | { |
| | | //下一关的门 |
| | | if (numParameter < 0 || numParameter > 3) |
| | | { |
| | | MessageBox.Show("参数必须是:0:上1:右2:下3:左"); |
| | | return; |
| | | } |
| | | ParametersPoint ng = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), numParameter); |
| | | if (this.housePathInfo.AddNextGate(ng)) |
| | | { |
| | | Canvas ngControl = CreateNextGateUI(ng); |
| | | this.HouseInfoLayer.Children.Add(ngControl); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | } |
| | | OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); |
| | | Point point = GetPosition(e); |
| | | if (op == OperateActionD.LoopLine) |
| | | { |
| | | //巡逻线 |
| | | if (!moveable) |
| | | { |
| | | return; |
| | | } |
| | | tempLine.X2 = point.X; |
| | | tempLine.Y2 = point.Y; |
| | | } |
| | | else if (op == OperateActionD.FindPathLine) |
| | | if (op == OperateActionD.FindPathLine) |
| | | { |
| | | //寻路线 |
| | | if (!moveable) |
| | |
| | | tempLine.X2 = point.X; |
| | | tempLine.Y2 = point.Y; |
| | | } |
| | | else if (op == OperateActionD.Obstacle) |
| | | else if (op == OperateActionD.Obstacle||op==OperateActionD.PathGuide) |
| | | { |
| | | //障碍物线 |
| | | if (!moveable) |
| | |
| | | OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); |
| | | Point point = GetPosition(e); |
| | | |
| | | if (op == OperateActionD.LoopLine) |
| | | { |
| | | //巡逻线 |
| | | if (!moveable) |
| | | { |
| | | return; |
| | | } |
| | | moveable = false; |
| | | if (tempLine == null) |
| | | { |
| | | return; |
| | | } |
| | | ZTPoint startPoint = (ZTPoint)tempLine.Tag; |
| | | ZTPoint centerPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); |
| | | if (!centerPoint.Equals(ZTPoint.Empty)) |
| | | { |
| | | ZTLinePoint ll = new ZTLinePoint(startPoint, centerPoint); |
| | | if (this.housePathInfo.AddLoopLine(ll)) |
| | | { |
| | | Line llline = CreateLoopLineUI(ll); |
| | | this.HouseInfoLayer.Children.Add(llline); |
| | | } |
| | | } |
| | | |
| | | this.HouseInfoLayer.Children.Remove(tempLine); |
| | | tempLine = null; |
| | | } |
| | | else if (op == OperateActionD.FindPathLine) |
| | | if (op == OperateActionD.FindPathLine) |
| | | { |
| | | //寻路线 |
| | | if (!moveable) |
| | |
| | | this.HouseInfoLayer.Children.Remove(tempLine); |
| | | tempLine = null; |
| | | } |
| | | else if (op == OperateActionD.Obstacle) |
| | | else if (op == OperateActionD.Obstacle|| op == OperateActionD.PathGuide) |
| | | { |
| | | //绘制障碍物 |
| | | //绘制障碍物或路径指导 |
| | | //判断是否起点 |
| | | if (tempPolyline == null) |
| | | { |
| | |
| | | return; |
| | | } |
| | | |
| | | if (IsFirstPoint(point) && this.points.Count > 2) |
| | | if (IsComplete(point) && this.points.Count > 2) |
| | | { |
| | | //到起点,完成,向houseinfo里添加障碍物 ,画折线, |
| | | ZTPoint[] obstaclePoints = new ZTPoint[this.points.Count]; |
| | | ZTPoint[] points = new ZTPoint[this.points.Count]; |
| | | for (int i = 0; i < this.points.Count; i++) |
| | | { |
| | | obstaclePoints[i] = new ZTPoint((Int32)this.points[i].X, (Int32)this.points[i].Y); |
| | | points[i] = new ZTPoint((Int32)this.points[i].X, (Int32)this.points[i].Y); |
| | | } |
| | | |
| | | ZTPolygon ztpolygon = new ZTPolygon(obstaclePoints); |
| | | this.housePathInfo.AddObstacle(ztpolygon); |
| | | ZTPolygon ztpolygon = new ZTPolygon(points); |
| | | if (op == OperateActionD.Obstacle) |
| | | { |
| | | //障碍物 |
| | | this.housePathInfo.AddObstacle(ztpolygon); |
| | | Polygon obstacle = CreateObstacleUI(ztpolygon); |
| | | this.HouseInfoLayer.Children.Add(obstacle); |
| | | } |
| | | else if (op == OperateActionD.PathGuide) |
| | | { |
| | | //路径导引 |
| | | string strParameter = this.tagParameter.Text; |
| | | string[] sp = strParameter.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); |
| | | if (sp.Length == 2) |
| | | { |
| | | ZTPoint targetPoint = new ZTPoint(TypeConverter.StringToInt(sp[0],0), TypeConverter.StringToInt(sp[1], 0)); |
| | | ZTTargetPolygon targetPolygon = new ZTTargetPolygon(ztpolygon, targetPoint); |
| | | |
| | | Polygon polygon = CreateObstacleUI(ztpolygon); |
| | | this.HouseInfoLayer.Children.Add(polygon); |
| | | |
| | | this.housePathInfo.AddPathGuide(targetPolygon); |
| | | var pathGuide = CreatePathGuideUI(targetPolygon); |
| | | this.PathGuideShapeLayer.Children.Add(pathGuide); |
| | | } |
| | | } |
| | | |
| | | this.HouseInfoLayer.Children.Remove(tempPolyline); |
| | | tempPolyline = null; |
| | | this.HouseInfoLayer.Children.Remove(tempLine); |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建巡逻线UI |
| | | /// </summary> |
| | | private Line CreateLoopLineUI(ZTLinePoint linePoint) |
| | | { |
| | | Line edgeLine = new Line(); |
| | | edgeLine.Tag = linePoint; |
| | | edgeLine.MouseRightButtonUp += LoopLine_MouseRightButtonUp; |
| | | edgeLine.Stroke = new SolidColorBrush(Colors.Red); |
| | | edgeLine.StrokeThickness = 6; |
| | | edgeLine.X1 = linePoint.X1; |
| | | edgeLine.Y1 = linePoint.Y1; |
| | | |
| | | edgeLine.X2 = linePoint.X2; |
| | | edgeLine.Y2 = linePoint.Y2; |
| | | |
| | | edgeLine.StrokeDashArray = new DoubleCollection() { 2, 3 }; |
| | | edgeLine.StrokeDashCap = PenLineCap.Triangle; |
| | | edgeLine.StrokeEndLineCap = PenLineCap.Square; |
| | | edgeLine.StrokeStartLineCap = PenLineCap.Round; |
| | | |
| | | |
| | | return edgeLine; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 巡逻线右击 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void LoopLine_MouseRightButtonUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | Line c = sender as Line; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ZTLinePoint fp = default(ZTLinePoint); |
| | | try |
| | | { |
| | | fp = (ZTLinePoint)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | if (this.housePathInfo.RemoveLoopLine(fp)) |
| | | { |
| | | this.HouseInfoLayer.Children.Remove(c); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 创建临时巡逻线UI |
| | |
| | | polygon.Opacity = 0.7f; |
| | | for (int i = 0; i < ztpolygon.Points.Length; i++) |
| | | { |
| | | polygon.Points.Add(new Point(ztpolygon.Points[i].X,ztpolygon.Points[i].Y)); |
| | | polygon.Points.Add(new Point(ztpolygon.Points[i].X, ztpolygon.Points[i].Y)); |
| | | } |
| | | |
| | | return polygon; |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 创建障碍物UI |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private Polygon CreatePathGuideUI(ZTTargetPolygon ztpolygon) |
| | | { |
| | | Polygon polygon = new Polygon(); |
| | | polygon.Tag = ztpolygon; |
| | | polygon.MouseRightButtonUp += PathGuide_MouseRightButtonUp; |
| | | polygon.MouseEnter += PathGuide_MouseEnter; |
| | | polygon.MouseLeave += PathGuide_MouseLeave; |
| | | polygon.StrokeThickness = 1; |
| | | polygon.Stroke = new SolidColorBrush(Colors.Yellow); |
| | | polygon.Fill = new SolidColorBrush(Colors.Yellow); |
| | | polygon.Opacity = 0.7f; |
| | | for (int i = 0; i < ztpolygon.Polygon.Points.Length; i++) |
| | | { |
| | | polygon.Points.Add(new Point(ztpolygon.Polygon.Points[i].X, ztpolygon.Polygon.Points[i].Y)); |
| | | } |
| | | |
| | | return polygon; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移出路径指导区域 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void PathGuide_MouseLeave(object sender, MouseEventArgs e) |
| | | { |
| | | this.PathGuideLayer.Children.Clear(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移入路径指导区域 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void PathGuide_MouseEnter(object sender, MouseEventArgs e) |
| | | { |
| | | Polygon c = sender as Polygon; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ZTTargetPolygon ztp = default(ZTTargetPolygon); |
| | | try |
| | | { |
| | | ztp = (ZTTargetPolygon)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | this.PathGuideLayer.Children.Clear(); |
| | | |
| | | |
| | | Canvas main = new Canvas(); |
| | | main.MouseRightButtonUp += NextGate_MouseRightButtonUp; |
| | | Canvas.SetLeft(main, ztp.Target.X); |
| | | Canvas.SetTop(main, ztp.Target.Y); |
| | | |
| | | Rectangle rect = new Rectangle(); |
| | | Canvas.SetLeft(rect, -10); |
| | | Canvas.SetTop(rect, -10); |
| | | rect.Width = 20; |
| | | rect.Height = 20; |
| | | rect.Stroke = new SolidColorBrush(Colors.Blue); |
| | | rect.StrokeThickness = 1; |
| | | rect.Fill = new SolidColorBrush(Colors.Blue); |
| | | rect.Opacity = 0.5f; |
| | | main.Children.Add(rect); |
| | | |
| | | Ellipse elli = new Ellipse(); |
| | | Canvas.SetLeft(elli, -2); |
| | | Canvas.SetTop(elli, -2); |
| | | elli.Width = 4; |
| | | elli.Height = 4; |
| | | elli.Stroke = new SolidColorBrush(Colors.Black); |
| | | elli.StrokeThickness = 1; |
| | | elli.Fill = new SolidColorBrush(Colors.Black); |
| | | main.Children.Add(elli); |
| | | |
| | | TextBlock tb = new TextBlock(); |
| | | tb.Text = ztp.Target.ToString(); |
| | | tb.FontSize = 9; |
| | | main.Children.Add(tb); |
| | | |
| | | this.PathGuideLayer.Children.Add(main); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 障碍物右键删除 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void PathGuide_MouseRightButtonUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | Polygon c = sender as Polygon; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ZTTargetPolygon ztp = default(ZTTargetPolygon); |
| | | try |
| | | { |
| | | ztp = (ZTTargetPolygon)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | if (this.housePathInfo.RemovePathGuide(ztp)) |
| | | { |
| | | this.PathGuideShapeLayer.Children.Remove(c); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建临时障碍物线UI |
| | |
| | | elli.StrokeThickness = 1; |
| | | elli.Fill = new SolidColorBrush(Colors.Black); |
| | | main.Children.Add(elli); |
| | | |
| | | |
| | | |
| | | return main; |
| | | } |
| | |
| | | |
| | | |
| | | return edgeLine; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建进入下一关的门UI |
| | | /// 外方内圆 |
| | | /// </summary> |
| | | private Canvas CreateNextGateUI(ParametersPoint point) |
| | | { |
| | | Canvas main = new Canvas(); |
| | | main.Tag = point; |
| | | main.MouseRightButtonUp += NextGate_MouseRightButtonUp; |
| | | Canvas.SetLeft(main, point.Point.X); |
| | | Canvas.SetTop(main, point.Point.Y); |
| | | |
| | | Rectangle rect = new Rectangle(); |
| | | Canvas.SetLeft(rect, -10); |
| | | Canvas.SetTop(rect, -10); |
| | | rect.Width = 20; |
| | | rect.Height = 20; |
| | | rect.Stroke = new SolidColorBrush(Colors.GreenYellow); |
| | | rect.StrokeThickness = 1; |
| | | rect.Fill = new SolidColorBrush(Colors.GreenYellow); |
| | | rect.Opacity = 0.5f; |
| | | main.Children.Add(rect); |
| | | |
| | | Ellipse elli = new Ellipse(); |
| | | Canvas.SetLeft(elli, -2); |
| | | Canvas.SetTop(elli, -2); |
| | | elli.Width = 4; |
| | | elli.Height = 4; |
| | | elli.Stroke = new SolidColorBrush(Colors.Black); |
| | | elli.StrokeThickness = 1; |
| | | elli.Fill = new SolidColorBrush(Colors.Black); |
| | | main.Children.Add(elli); |
| | | |
| | | TextBlock tb = new TextBlock(); |
| | | tb.Text = point.Parameter.ToString(); |
| | | tb.FontSize = 9; |
| | | main.Children.Add(tb); |
| | | |
| | | |
| | | return main; |
| | | } |
| | | |
| | | private void NextGate_MouseRightButtonUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | Canvas c = sender as Canvas; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ParametersPoint fp = default(ParametersPoint); |
| | | try |
| | | { |
| | | fp = (ParametersPoint)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | if (this.housePathInfo.RemoveNextGate(fp)) |
| | | { |
| | | this.HouseInfoLayer.Children.Remove(c); |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建循环点界面 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private Canvas CreateLoopPointUI(ZTPoint point) |
| | | { |
| | | Canvas main = new Canvas(); |
| | | main.Tag = point; |
| | | main.MouseRightButtonUp += LoopPoint_MouseRightButtonUp; |
| | | Canvas.SetLeft(main, point.X); |
| | | Canvas.SetTop(main, point.Y); |
| | | |
| | | Rectangle rect = new Rectangle(); |
| | | Canvas.SetLeft(rect, -10); |
| | | Canvas.SetTop(rect, -10); |
| | | rect.Width = 20; |
| | | rect.Height = 20; |
| | | rect.Stroke = new SolidColorBrush(Colors.OrangeRed); |
| | | rect.StrokeThickness = 1; |
| | | rect.Fill = new SolidColorBrush(Colors.OrangeRed); |
| | | rect.Opacity = 0.5f; |
| | | main.Children.Add(rect); |
| | | |
| | | Ellipse elli = new Ellipse(); |
| | | Canvas.SetLeft(elli, -2); |
| | | Canvas.SetTop(elli, -2); |
| | | elli.Width = 4; |
| | | elli.Height = 4; |
| | | elli.Stroke = new SolidColorBrush(Colors.Black); |
| | | elli.StrokeThickness = 1; |
| | | elli.Fill = new SolidColorBrush(Colors.Black); |
| | | main.Children.Add(elli); |
| | | |
| | | return main; |
| | | } |
| | | |
| | | |
| | | private void LoopPoint_MouseRightButtonUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | Canvas c = sender as Canvas; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ZTPoint fp = default(ZTPoint); |
| | | |
| | | try |
| | | { |
| | | fp = (ZTPoint)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | this.housePathInfo.LoopPoint = ZTPoint.Empty; |
| | | this.HouseInfoLayer.Children.Remove(c); |
| | | } |
| | | #endregion |
| | | |
| | |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private bool IsFirstPoint(Point point) |
| | | private bool IsComplete(Point point) |
| | | { |
| | | Point temp = this.points[0]; |
| | | if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10) |
| | |
| | | Obstacle = 0,//障碍物 |
| | | LocationPoint,//定位点 |
| | | FindPathPoint,//寻路点 |
| | | LoopLine,//循环线 |
| | | FindPathLine,//寻路线 |
| | | LoopPoint,//循环点 |
| | | NextGate,//入门点 |
| | | PathGuide,//路径引导 |
| | | ReadCoordinate,//读取坐标 |
| | | StartEndPoint,//测试起终点 |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | |
| | | if (rects.Count <= 0) |
| | | { |
| | | return Structs.ZTPoint.Empty; |
| | | return ZTPoint.Empty; |
| | | } |
| | | |
| | | //主角位置 |
| | | Structs.ZTPoint rolePosition = gameRect.Start + new Structs.ZTPoint(rects[0].Start.X + rolePositionOffset.Width, rects[0].Start.Y + rolePositionOffset.Height); |
| | | ZTPoint rolePosition = gameRect.Start.Add(rects[0].Start.X + rolePositionOffset.Width, rects[0].Start.Y + rolePositionOffset.Height); |
| | | |
| | | return rolePosition; |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | #region Location Point 1 |
| | | private static readonly Hsv LocationPointMinHsv = new Hsv(0, 0, 0); |
| | | private static readonly Hsv LocationPointMaxHsv = new Hsv(0, 0, 5); |
| | | private static readonly ZTSize LocationPointMinLimitSize = new ZTSize(33, 33); |
| | |
| | | |
| | | return true; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region Location Point 2 |
| | | private static ColorArray LocationPoint = ColorArray.FromColorString(0, 0, "800,352,0,0,0$791,343,255,255,255$793,343,0,0,0$796,343,255,255,255$798,343,0,0,0$801,343,255,255,255$802,345,0,0,0$802,347,255,255,255$802,349,0,0,0$802,352,255,255,255$797,352,255,255,255$795,352,0,0,0$791,352,255,255,255$791,350,0,0,0$791,348,255,255,255$791,346,0,0,0$796,347,255,255,255$797,348,255,255,255"); |
| | | /// <summary> |
| | | /// 获取定位点 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="gameRect"></param> |
| | | /// <returns></returns> |
| | | public static ParametersPoint GetLocationPoint(Image<Rgb,byte> image,ZTRectangle gameRect) |
| | | { |
| | | ZTRectangle rect = ZTRectangle.Empty; |
| | | if (CVHelper.FindColorArray(out rect, image, LocationPoint, gameRect)) |
| | | { |
| | | //获取定位标记,解析参数 |
| | | byte number = 0; |
| | | bool bitValue = true; |
| | | |
| | | Int32 x = 0, y = 0; |
| | | for (int bitIndex = 0; bitIndex <= 7; bitIndex++) |
| | | { |
| | | //获取图像中存值的坐标 |
| | | GetBitCoordinate(out x, out y, bitIndex); |
| | | |
| | | //解析并设置值 |
| | | if (!ParseBit(out bitValue, image, rect.Start.Add(x, y))) |
| | | { |
| | | return ParametersPoint.Empty; |
| | | } |
| | | else |
| | | { |
| | | number=SetBit(number, bitIndex, bitValue); |
| | | } |
| | | } |
| | | |
| | | return new ParametersPoint(rect.GetCenterPoint(), number); |
| | | |
| | | } |
| | | |
| | | return ParametersPoint.Empty; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置指定位 |
| | | /// </summary> |
| | | /// <param name="number"></param> |
| | | /// <param name="bitIndex"></param> |
| | | /// <param name="bitValue"></param> |
| | | /// <returns></returns> |
| | | private static byte SetBit(byte number, Int32 bitIndex,bool bitValue) |
| | | { |
| | | byte twonumber = 0; |
| | | switch (bitIndex) |
| | | { |
| | | case 0: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b00000001; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b11111110; |
| | | } |
| | | break; |
| | | case 1: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b00000010; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b11111101; |
| | | } |
| | | break; |
| | | case 2: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b00000100; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b11111011; |
| | | } |
| | | break; |
| | | case 3: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b00001000; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b11110111; |
| | | } |
| | | break; |
| | | case 4: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b00010000; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b11101111; |
| | | } |
| | | break; |
| | | case 5: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b00100000; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b11011111; |
| | | } |
| | | break; |
| | | case 6: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b01000000; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b10111111; |
| | | } |
| | | break; |
| | | case 7: |
| | | if (bitValue) |
| | | { |
| | | twonumber = 0b10000000; |
| | | } |
| | | else |
| | | { |
| | | twonumber = 0b01111111; |
| | | } |
| | | break; |
| | | } |
| | | |
| | | if (bitValue) |
| | | { |
| | | return (byte)(number | twonumber); |
| | | } |
| | | else |
| | | { |
| | | return (byte)(number & twonumber); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 得到指定位坐标 |
| | | /// </summary> |
| | | /// <param name="x"></param> |
| | | /// <param name="y"></param> |
| | | /// <param name="bitIndex"></param> |
| | | private static void GetBitCoordinate(out Int32 x, out Int32 y, Int32 bitIndex) |
| | | { |
| | | x = 0; |
| | | y = 0; |
| | | switch (bitIndex) |
| | | { |
| | | case 0: |
| | | x = 8; |
| | | y = 6; |
| | | break; |
| | | case 1: |
| | | x = 6; |
| | | y = 6; |
| | | break; |
| | | case 2: |
| | | x = 4; |
| | | y = 6; |
| | | break; |
| | | case 3: |
| | | x = 2; |
| | | y = 6; |
| | | break; |
| | | case 4: |
| | | x = 8; |
| | | y = 2; |
| | | break; |
| | | case 5: |
| | | x = 6; |
| | | y = 2; |
| | | break; |
| | | case 6: |
| | | x = 4; |
| | | y = 2; |
| | | break; |
| | | case 7: |
| | | x = 2; |
| | | y = 2; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 解析位状态 |
| | | /// true:1 |
| | | /// false:0 |
| | | /// </summary> |
| | | /// <param name="bit"></param> |
| | | /// <param name="image"></param> |
| | | /// <param name="x"></param> |
| | | /// <param name="y"></param> |
| | | /// <returns>true:解析成功,false:解析失败</returns> |
| | | private static bool ParseBit(out bool bit,Image<Rgb, byte> image, ZTPoint point) |
| | | { |
| | | bit = true; |
| | | if (image.Data[point.Y, point.X, 0] == 0xff && image.Data[point.Y, point.X, 1] == 0xff && image.Data[point.Y, point.X, 2] == 0xff&& |
| | | image.Data[point.Y, point.X+1, 0] == 0xff && image.Data[point.Y, point.X+1, 1] == 0xff && image.Data[point.Y, point.X+1, 2] == 0xff&& |
| | | image.Data[point.Y+1, point.X, 0] == 0xff && image.Data[point.Y+1, point.X, 1] == 0xff && image.Data[point.Y+1, point.X, 2] == 0xff&& |
| | | image.Data[point.Y+1, point.X+1, 0] == 0xff && image.Data[point.Y+1, point.X+1, 1] == 0xff && image.Data[point.Y+1, point.X+1, 2] == 0xff) |
| | | { |
| | | //白 |
| | | bit = true; |
| | | return true; |
| | | } |
| | | |
| | | if (image.Data[point.Y, point.X, 0] == 0x00 && image.Data[point.Y, point.X, 1] == 0x00 && image.Data[point.Y, point.X, 2] == 0x00 && |
| | | image.Data[point.Y, point.X + 1, 0] == 0x00 && image.Data[point.Y, point.X + 1, 1] == 0x00 && image.Data[point.Y, point.X + 1, 2] == 0x00 && |
| | | image.Data[point.Y + 1, point.X, 0] == 0x00 && image.Data[point.Y + 1, point.X, 1] == 0x00 && image.Data[point.Y + 1, point.X, 2] == 0x00 && |
| | | image.Data[point.Y + 1, point.X + 1, 0] == 0x00 && image.Data[point.Y + 1, point.X + 1, 1] == 0x00 && image.Data[point.Y + 1, point.X + 1, 2] == 0x00) |
| | | { |
| | | //黑 |
| | | bit = false; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | #endregion |
| | | #region minimap |
| | | |
| | | /// <summary> |
| | | /// 小方格色块偏移 |
| | | /// </summary> |
| | | private static ZTPoint[] colorOffset = new ZTPoint[] { |
| | | new ZTPoint(2,14), |
| | | new ZTPoint(2,15), |
| | | new ZTPoint(15,14), |
| | | new ZTPoint(15,15), |
| | | }; |
| | | |
| | | /// <summary> |
| | | /// 已经走过的房间颜色(青色) |
| | | /// </summary> |
| | | private static ZTHsvFloatColor crossedColorMin = new ZTHsvFloatColor(0.498, 0.998, 0.998); |
| | | private static ZTHsvFloatColor crossedColorMax = new ZTHsvFloatColor(0.502, 1, 1); |
| | | /// <summary> |
| | | /// 是否穿越过的房间(青色) |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="x"></param> |
| | | /// <param name="y"></param> |
| | | /// <returns></returns> |
| | | public static bool IsCrossedHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y) |
| | | { |
| | | if (CVHelper.InRange(image.Data, x, y, crossedColorMin, crossedColorMax, colorOffset)) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 当前房间颜色(蓝色) |
| | | /// </summary> |
| | | private static ZTHsvFloatColor currentHouseColorMin = new ZTHsvFloatColor(0.665f, 0.998, 0.998); |
| | | private static ZTHsvFloatColor currentHouseColorMax = new ZTHsvFloatColor(0.669f, 1, 1); |
| | | /// <summary> |
| | | /// 是否当前房间(蓝色) |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="minMapStart"></param> |
| | | /// <param name="houseIndex"></param> |
| | | /// <returns></returns> |
| | | public static bool IsCurrentHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y) |
| | | { |
| | | if (CVHelper.InRange(image.Data, x, y, currentHouseColorMin, currentHouseColorMax, colorOffset)) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 下一房间颜色(绿色) |
| | | /// </summary> |
| | | private static ZTHsvFloatColor nextHouseColorMin = new ZTHsvFloatColor(0.298f, 0.998, 0.998); |
| | | private static ZTHsvFloatColor nextHouseColorMax = new ZTHsvFloatColor(0.302, 1, 1); |
| | | /// <summary> |
| | | /// 是否下一房间,绿色 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="minMapStart"></param> |
| | | /// <param name="houseIndex"></param> |
| | | /// <returns></returns> |
| | | public static bool IsNextHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y) |
| | | { |
| | | if (CVHelper.InRange(image.Data, x, y, nextHouseColorMin, nextHouseColorMax, colorOffset)) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 最终房间颜色(红色1) |
| | | /// </summary> |
| | | private static ZTHsvFloatColor overHouse1ColorMin = new ZTHsvFloatColor(0, 0.998, 0.998); |
| | | private static ZTHsvFloatColor overHouse1ColorMax = new ZTHsvFloatColor(0.002, 1, 1); |
| | | |
| | | /// <summary> |
| | | /// 最终房间颜色(红色2) |
| | | /// </summary> |
| | | private static ZTHsvFloatColor overHouse2ColorMin = new ZTHsvFloatColor(0.998, 0.998, 0.998); |
| | | private static ZTHsvFloatColor overHouse2ColorMax = new ZTHsvFloatColor(1.0f, 1, 1); |
| | | |
| | | /// <summary> |
| | | /// 是否最终房间 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="minMapStart"></param> |
| | | /// <param name="houseIndex"></param> |
| | | /// <returns></returns> |
| | | public static bool IsOverHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y) |
| | | { |
| | | if (CVHelper.InRange(image.Data, x, y, overHouse1ColorMin, overHouse1ColorMax, colorOffset) |
| | | || CVHelper.InRange(image.Data, x, y, overHouse2ColorMin, overHouse2ColorMax, colorOffset)) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | } |
| New file |
| | |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.CV |
| | | { |
| | | public class KaleteCVHelper |
| | | { |
| | | /// <summary> |
| | | /// 卡勒特难度,1¬5级 |
| | | /// </summary> |
| | | private static ColorArray[] KaleteNandu = new ColorArray[] { |
| | | ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.002f, "835,221,0,88,149$821,221,255,255,255$822,221,255,255,255$834,221,0,88,149$861,221,143,0,119$862,221,143,0,119$874,221,149,0,17$875,221,149,0,17"), |
| | | ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.002f, "848,221,88,0,149$821,221,88,149,0$822,221,88,149,0$834,221,255,255,255$835,221,255,255,255$849,221,88,0,149$861,221,143,0,119$862,221,143,0,119$874,221,149,0,17$875,221,149,0,17"), |
| | | ColorArray.FromHsvFloatString(0.002f,0.002f,0.002f,"848,221,255,255,255$822,221,88,149,0$835,221,0,88,149$862,221,143,0,119$875,221,149,0,17"), |
| | | ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.002f, "848,221,88,0,149$822,221,88,149,0$835,221,0,88,149$862,221,255,255,255$875,221,149,0,17"), |
| | | ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.002f, "848,221,88,0,149$822,221,88,149,0$835,221,0,88,149$862,221,143,0,119$874,221,255,255,255") |
| | | }; |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 查找凛冬难度 |
| | | /// </summary> |
| | | /// <param name="choiceNandu"></param> |
| | | /// <param name="image"></param> |
| | | /// <param name="gameRect"></param> |
| | | /// <returns></returns> |
| | | public static bool GetChoiceKaleteNandu(out Int32 choiceNandu, Image<Rgb, byte> image, ZTRectangle gameRect) |
| | | { |
| | | ZTRectangle limit = new ZTRectangle(gameRect.Start.X + 780, gameRect.Start.Y + 191, gameRect.Start.X + 911, gameRect.Start.Y + 234); |
| | | ZTRectangle position = ZTRectangle.Empty; |
| | | for (int i = 0; i < KaleteNandu.Length; i++) |
| | | { |
| | | if (CVHelper.FindColorArray(out position, image, KaleteNandu[i], limit)) |
| | | { |
| | | choiceNandu = i + 1; |
| | | return true; |
| | | } |
| | | } |
| | | choiceNandu = 0; |
| | | return false; |
| | | } |
| | | |
| | | |
| | | public static ColorArray KaleteTopText = ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.3f, "1119,8,204,193,167$1102,8,0,0,0$1103,8,204,193,167$1104,8,0,0,0$1112,8,0,0,0$1113,8,204,193,167$1114,8,0,0,0$1115,8,204,193,167$1116,8,0,0,0$1118,8,0,0,0$1120,8,0,0,0$1124,8,0,0,0$1125,8,204,193,167$1126,8,0,0,0$1129,8,0,0,0$1130,8,204,193,167$1131,8,0,0,0$1137,8,0,0,0$1138,8,204,193,167$1139,8,0,0,0$1146,8,0,0,0$1147,8,204,193,167$1148,8,0,0,0$1156,19,0,0,0$1155,19,204,193,167$1154,19,204,193,167$1153,19,0,0,0$1151,19,0,0,0$1150,19,204,193,167$1149,19,0,0,0$1148,19,204,193,167$1147,19,0,0,0$1145,19,0,0,0$1144,19,204,193,167$1141,19,204,193,167$1140,19,204,193,167$1139,19,204,193,167$1138,19,0,0,0$1136,19,0,0,0$1135,19,204,193,167$1134,19,0,0,0$1132,19,0,0,0$1131,19,204,193,167$1129,19,204,193,167$1128,19,0,0,0$1126,19,0,0,0$1125,19,204,193,167$1124,19,0,0,0$1121,19,0,0,0$1120,19,204,193,167$1119,19,204,193,167$1118,19,0,0,0$1117,19,204,193,167$1116,19,0,0,0$1114,19,204,193,167$1113,19,0,0,0$1104,19,0,0,0$1103,19,204,193,167$1102,19,0,0,0$1114,9,204,193,167$1114,10,0,0,0$1114,12,204,193,167$1114,13,204,193,167$1114,14,204,193,167$1114,15,204,193,167$1114,16,204,193,167$1114,17,204,193,167$1114,18,204,193,167$1114,19,204,193,167$1130,20,0,0,0$1130,18,0,0,0$1129,18,0,0,0$1129,17,204,193,167$1129,16,0,0,0$1129,14,204,193,167$1129,13,0,0,0$1129,12,204,193,167$1129,11,0,0,0$1129,10,204,193,167$1129,9,0,0,0"); |
| | | /// <summary> |
| | | /// 房间上是否存在卡勒特之初的文字 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="gameRect"></param> |
| | | /// <returns></returns> |
| | | public static bool ExistKaleteText(Image<Rgb, byte> image, ZTRectangle gameRect) |
| | | { |
| | | ZTRectangle limit = new ZTRectangle(gameRect.End.X - 200, gameRect.Start.Y, gameRect.End.X, gameRect.Start.Y + 40); |
| | | ZTRectangle position = ZTRectangle.Empty; |
| | | return CVHelper.FindColorArray(out position, image, KaleteTopText, limit); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | public class LindongCVHelper |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 小地图怪物颜色 |
| | | /// </summary> |
| | | private static ZTHsvFloatColor minMinimapMainMonsterColor = new ZTHsvFloatColor(0.054f, 0.098f, 0.896f); |
| | | private static ZTHsvFloatColor maxMinimapMainMonsterColor = new ZTHsvFloatColor(0.068f, 1.0f, 1.0f); |
| | | |
| | | /// <summary> |
| | | /// 小地图主角颜色 |
| | | /// </summary> |
| | | private static ZTHsvFloatColor minMinimapRoleColor = new ZTHsvFloatColor(0.508f, 0.860f, 0.731f); |
| | | private static ZTHsvFloatColor maxMinimapRoleColor = new ZTHsvFloatColor(0.609f, 1f , 1f); |
| | | |
| | | /// <summary> |
| | | /// 小方格主角偏移 |
| | | /// </summary> |
| | | private static Structs.ZTPoint[] houseRoleBlockOffset = new Structs.ZTPoint[] { |
| | | new Structs.ZTPoint(0,0), |
| | | new Structs.ZTPoint(1,0), |
| | | new Structs.ZTPoint(0,1), |
| | | new Structs.ZTPoint(1,1) |
| | | }; |
| | | |
| | | /// <summary> |
| | | /// 得到当前角色所在房间 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="minMapStart"></param> |
| | | /// <param name="offset"></param> |
| | | /// <returns></returns> |
| | | public static bool GetCurrentHouseIndex(out Int32 houseIndex, Image<Rgb, byte> image, Structs.ZTPoint minMapStart) |
| | | { |
| | | houseIndex = -1; |
| | | Int32 mainMonsterHouseIndex = -1; |
| | | for (int i = 0; i < 20; i++) |
| | | { |
| | | Int32 row = i / 4; |
| | | Int32 col = i % 4; |
| | | |
| | | //目标块第一块坐标 |
| | | Int32 x = minMapStart.X + col * 18; |
| | | Int32 y = minMapStart.Y + row * 18; |
| | | |
| | | Structs.ZTPoint position = Structs.ZTPoint.Empty; |
| | | ZTRectangle limit = new ZTRectangle(x, y, x + 17, y + 17); |
| | | if (CVHelper.FindColorBlock(out position, image, limit, minMinimapRoleColor, maxMinimapRoleColor, houseRoleBlockOffset)) |
| | | { |
| | | houseIndex = i; |
| | | return true; |
| | | } |
| | | |
| | | if (i == 15 ) |
| | | { |
| | | //查看,14格是否青色 |
| | | if (CVHelper.InRange(image.Data, x-18, y, minMinimapCurrentColor, maxMinimapCurrentColor, houseColorBlockOffset)) |
| | | { |
| | | //是否怪物图像 |
| | | if (CVHelper.FindColorBlock(out position, image, limit, minMinimapMainMonsterColor, maxMinimapMainMonsterColor, houseRoleBlockOffset)) |
| | | { |
| | | mainMonsterHouseIndex = 15; |
| | | break; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | | if (mainMonsterHouseIndex > -1) |
| | | { |
| | | houseIndex = mainMonsterHouseIndex; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 小地图已经走过的房间颜色(青色) |
| | | /// </summary> |
| | | private static ZTHsvFloatColor minMinimapCurrentColor = new ZTHsvFloatColor(0.498, 0.998, 0.998); |
| | | private static ZTHsvFloatColor maxMinimapCurrentColor = new ZTHsvFloatColor(0.502, 1, 1); |
| | | |
| | | /// <summary> |
| | | /// 小地图下一个房间的颜色(绿色) |
| | | /// </summary> |
| | | private static ZTHsvFloatColor minMinimapNextColor = new ZTHsvFloatColor(0.298, 0.998, 0.998); |
| | | private static ZTHsvFloatColor maxMinimapNextColor = new ZTHsvFloatColor(0.302, 1, 1); |
| | | /// <summary> |
| | | /// 小方格色块偏移 |
| | | /// </summary> |
| | | private static Structs.ZTPoint[] houseColorBlockOffset = new Structs.ZTPoint[] { |
| | | new Structs.ZTPoint(2,2), |
| | | new Structs.ZTPoint(2,3), |
| | | new Structs.ZTPoint(15,14), |
| | | new Structs.ZTPoint(15,15), |
| | | }; |
| | | /// <summary> |
| | | /// 房间是否开放 |
| | | /// </summary> |
| | | /// <param name="houseIndex"></param> |
| | | /// <returns></returns> |
| | | public static bool HouseIsOpen(Image<Rgb, byte> image, Structs.ZTPoint minMapStart, Int32 houseIndex) |
| | | { |
| | | //第一块距上边15px,距左边1px |
| | | Int32 row = houseIndex / 4; |
| | | Int32 col = houseIndex % 4; |
| | | |
| | | //目标块第一块坐标 |
| | | Int32 x = minMapStart.X + col * 18; |
| | | Int32 y = minMapStart.Y + row * 18; |
| | | |
| | | byte[,,] data = image.Data; |
| | | if (CVHelper.InRange(data, x, y, minMinimapNextColor, maxMinimapNextColor, houseColorBlockOffset)) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | if (CVHelper.InRange(data, x, y, minMinimapCurrentColor, maxMinimapCurrentColor, houseColorBlockOffset)) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | private static Hsv minMonsterHsv = new Hsv(165, 247, 175); |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Dnf |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 移动意图 |
| | | /// </summary> |
| | | public enum MoveIntent |
| | | { |
| | | None,//没移动 |
| | | AttackMove,//去攻击 |
| | | FindDoorMove,//去找门 |
| | | FindRoleMove,//找主角 |
| | | PickupMove//去拾取 |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Dnf |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 移动方式 |
| | | /// </summary> |
| | | public enum MoveMethod |
| | | { |
| | | Vertical,//默认垂直移动 |
| | | ToLeft,//左移动 |
| | | ToRight,//右移动 |
| | | Fixed//固定离动距离 |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Dnf |
| | | { |
| | | /// <summary> |
| | | /// 速度计算 |
| | | /// </summary> |
| | | public class SpeedProvider |
| | | { |
| | | public static SpeedProvider Define = new SpeedProvider(1400); |
| | | public SpeedProvider(Int32 speed) |
| | | { |
| | | double stepPixelPerSpeedX = 0;//步行 X每个速度一秒移动的像素数 |
| | | double stepPixelPerSpeedY = 0;//步行 Y每个速度半秒移动的像素数 |
| | | double runPixelPerSpeedX = 0;//跑 X每个速度一秒移动的像素数 |
| | | if (speed <= 1109) |
| | | { |
| | | stepPixelPerSpeedX = 160d/1109d; |
| | | stepPixelPerSpeedY = 127d/1109d; |
| | | runPixelPerSpeedX = 260d/1109d; |
| | | } |
| | | else if (speed > 1109 && speed <= 1151) |
| | | { |
| | | stepPixelPerSpeedX = 166.5d/1151d; |
| | | stepPixelPerSpeedY = 131d/1151d; |
| | | runPixelPerSpeedX = 267.7d/1151d; |
| | | } |
| | | else if (speed > 1151 && speed <= 1256) |
| | | { |
| | | stepPixelPerSpeedX = 180d/1256d; |
| | | stepPixelPerSpeedY = 142.5d/1256d; |
| | | runPixelPerSpeedX = 284.5d/1256d; |
| | | } |
| | | else if (speed > 1256 && speed <= 1400) |
| | | { |
| | | stepPixelPerSpeedX = 194.5d/1400d; |
| | | stepPixelPerSpeedY = 156.5d/1400d; |
| | | runPixelPerSpeedX = 320d/1400d; |
| | | } |
| | | else |
| | | { |
| | | stepPixelPerSpeedX = 194.5d / 1400d; |
| | | stepPixelPerSpeedY = 156.5d / 1400d; |
| | | runPixelPerSpeedX = 320d/ 1400d; |
| | | } |
| | | |
| | | stepX = (stepPixelPerSpeedX * speed) / 1000; |
| | | stepY = (stepPixelPerSpeedY * speed) / 1000; |
| | | runX = (runPixelPerSpeedX * speed) / 800; |
| | | |
| | | |
| | | RunThresold = stepX * RandomUtils.KeyPressDurationMax +runX * RandomUtils.KeyPressDurationMax; |
| | | |
| | | RandomMoveMillSecond = (Int32)(300 / stepX); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 开始跑的阀值 |
| | | /// </summary> |
| | | public double RunThresold { get; private set; } |
| | | |
| | | //随机移动时间 |
| | | public Int32 RandomMoveMillSecond { get; private set; } |
| | | |
| | | private double stepX; |
| | | /// <summary> |
| | | /// 步行X轴速度 |
| | | /// </summary> |
| | | public double StepX |
| | | { |
| | | get |
| | | { |
| | | return stepX; |
| | | } |
| | | } |
| | | |
| | | private double stepY; |
| | | /// <summary> |
| | | /// 步行Y轴速度 |
| | | /// </summary> |
| | | public double StepY |
| | | { |
| | | get |
| | | { |
| | | return stepY; |
| | | } |
| | | } |
| | | |
| | | private double runX; |
| | | /// <summary> |
| | | /// 跑 X轴速度 |
| | | /// </summary> |
| | | public double RunX |
| | | { |
| | | get |
| | | { |
| | | return runX; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 跑 Y轴速度 |
| | | /// </summary> |
| | | public double RunY |
| | | { |
| | | get |
| | | { |
| | | return StepY; |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Maps |
| | | { |
| | | /// <summary> |
| | | /// 路径信息 |
| | | /// </summary> |
| | | public class FindPathInfo |
| | | { |
| | | public FindPathInfo() |
| | | { |
| | | Vertexs = new List<VertexInfo>(); |
| | | Edges = new List<EdgeInfo>(); |
| | | Positions = new List<PointSerialize>(); |
| | | } |
| | | |
| | | public FindPathInfo(Int32 width,Int32 height,Int32 rowcount,Int32 colcount):this() |
| | | { |
| | | this.Width = width; |
| | | this.Height = height; |
| | | this.RowCount = rowcount; |
| | | this.ColCount = colcount; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 宽 |
| | | /// </summary> |
| | | public int Width { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 高 |
| | | /// </summary> |
| | | public int Height { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 行数量 |
| | | /// </summary> |
| | | public int RowCount { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 列数量 |
| | | /// </summary> |
| | | public int ColCount { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 顶点列表,顶点x_index,y_index |
| | | /// </summary> |
| | | public List<VertexInfo> Vertexs { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 顶点连接信息,线信息ZTPoint是index ->index |
| | | /// </summary> |
| | | public List<EdgeInfo> Edges { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 定位信息 |
| | | /// </summary> |
| | | public List<PointSerialize> Positions { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 添加靠近点 |
| | | /// </summary> |
| | | /// <param name="vertex"></param> |
| | | public void AddVertex(Int32 index,Int32 vertexType,Int32 nearVetexIndex) |
| | | { |
| | | VertexInfo vertex = new VertexInfo() { Index = index, VertexType = vertexType, NearVertexIndex = nearVetexIndex }; |
| | | AddVertex(vertex); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 添加靠近点 |
| | | /// </summary> |
| | | /// <param name="vertex"></param> |
| | | public void AddVertex(VertexInfo vertex) |
| | | { |
| | | for (int i = 0; i < Vertexs.Count; i++) |
| | | { |
| | | if (Vertexs[i].Index ==vertex.Index) |
| | | { |
| | | this.Vertexs[i] = vertex; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | this.Vertexs.Add(vertex); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 是否存在顶点 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <returns></returns> |
| | | public bool VertexCanAddEdge(Int32 index) |
| | | { |
| | | for (int i = 0; i < this.Vertexs.Count; i++) |
| | | { |
| | | if (this.Vertexs[i].Index==index) |
| | | { |
| | | if (this.Vertexs[i].VertexType != 1) |
| | | { |
| | | return true; |
| | | } |
| | | else |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 得到顶点的行列 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <returns></returns> |
| | | public void GetVertexRowColumn(out Int32 row,out Int32 col,int index) |
| | | { |
| | | row = index / this.ColCount; |
| | | col = index % this.ColCount; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取json |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public string ToJsonString() |
| | | { |
| | | string json = ZTImage.Json.JsonBuilder.ToJsonString(this); |
| | | return json; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 从json字符串生成对象 |
| | | /// </summary> |
| | | /// <param name="json"></param> |
| | | /// <returns></returns> |
| | | public static FindPathInfo FromJsonString(string json) |
| | | { |
| | | return ZTImage.Json.JsonParser.ToObject<FindPathInfo>(json); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 顶点信息 |
| | | /// </summary> |
| | | public class VertexInfo |
| | | { |
| | | /// <summary> |
| | | /// 顶点索引 |
| | | /// </summary> |
| | | public Int32 Index { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 顶点类型,0:普通顶点,1:依附顶点,2:起点,3:终点 |
| | | /// </summary> |
| | | public Int32 VertexType { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 依附顶点所依附顶点的索引 |
| | | /// </summary> |
| | | public Int32 NearVertexIndex { get; set; } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 边信息 |
| | | /// </summary> |
| | | public class EdgeInfo |
| | | { |
| | | /// <summary> |
| | | /// 起点索引 |
| | | /// </summary> |
| | | public Int32 StartIndex { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 终点索引 |
| | | /// </summary> |
| | | public Int32 EndIndex { get; set; } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 可序列化点 |
| | | /// </summary> |
| | | public class PointSerialize |
| | | { |
| | | public PointSerialize() |
| | | {} |
| | | |
| | | public PointSerialize(Int32 x, Int32 y,Int32 number) |
| | | { |
| | | this.X = x; |
| | | this.Y = y; |
| | | this.Parameter = number; |
| | | } |
| | | public int X { get; set; } |
| | | |
| | | public int Y { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 参数 |
| | | /// </summary> |
| | | public Int32 Parameter { get; set; } |
| | | |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using RichCreator.Utility.Skills; |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.PathFinding; |
| | | using RichCreator.Utility.Utilitys; |
| | | |
| | | namespace RichCreator.Utility.Maps |
| | | { |
| | | /// <summary> |
| | | /// 房间信息 |
| | | /// </summary> |
| | | public class HouseInfo |
| | | { |
| | | public HouseInfo(HousePathInfo houseInfo) |
| | | { |
| | | this.HousePathInfo = houseInfo; |
| | | InitPathInfo(); |
| | | } |
| | | |
| | | public HouseInfo(Int32 index,MapType mapType,bool isEnd, HIDCode[] skills) |
| | | { |
| | | this.Index = index; |
| | | this.MapType = mapType; |
| | | this.IsEnd = isEnd; |
| | | |
| | | Skills = new SkillQueue(); |
| | | for (int i = 0; skills!=null&&i < skills.Length; i++) |
| | | { |
| | | Skills.EnQueue(false,skills[i]); |
| | | } |
| | | |
| | | if (index < 0) |
| | | { |
| | | throw new ArgumentOutOfRangeException("houseIndex"); |
| | | } |
| | | |
| | | try |
| | | { |
| | | this.HousePathInfo = HousePathInfo.From(this.MapType, index); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw e; |
| | | } |
| | | |
| | | InitPathInfo(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 房间编号 |
| | | /// </summary> |
| | | public Int32 Index { get; set; } |
| | | |
| | | ///// <summary> |
| | | ///// 下一房间编号 |
| | | ///// </summary> |
| | | //public Int32 NextIndex { get; set; } |
| | | |
| | | ///// <summary> |
| | | ///// 判断下一房间是否打开索引 |
| | | ///// </summary> |
| | | //public Int32 OpenStatusDetectIndex { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 门的位置 |
| | | /// </summary> |
| | | public Direction[] DoorDirection { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 技能队列 |
| | | /// </summary> |
| | | public SkillQueue Skills { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 房间的Y轴中间线,为负值,代表从游戏框向上移的像素值 |
| | | /// </summary> |
| | | public Int32 HouseCenterMoveLine { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 是否为结束房间 |
| | | /// </summary> |
| | | public bool IsEnd { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 地图类型 |
| | | /// </summary> |
| | | public MapType MapType { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 房间信息 |
| | | /// </summary> |
| | | public HousePathInfo HousePathInfo { get; private set; } |
| | | |
| | | /// <summary> |
| | | /// 路径查找器 |
| | | /// </summary> |
| | | private Dijkstra<ZTPoint> PathFinder { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 定位字典 |
| | | /// </summary> |
| | | private Dictionary<Int32, ZTPoint> LocationDic = new Dictionary<int, ZTPoint>(); |
| | | |
| | | /// <summary> |
| | | /// 屏幕坐标转地图坐标 |
| | | /// </summary> |
| | | /// <param name="screenCoordinate"></param> |
| | | /// <param name="locationParameter"></param> |
| | | /// <param name="locationCoordinate"></param> |
| | | /// <returns></returns> |
| | | public ZTPoint ScreenToMapCoordinate(ZTPoint screenCoordinate,ParametersPoint locationCoor) |
| | | { |
| | | if (!LocationDic.ContainsKey(locationCoor.Parameter)) |
| | | { |
| | | throw new ArgumentOutOfRangeException("不存在的定位点,parameter:" + locationCoor.Parameter.ToString()); |
| | | } |
| | | |
| | | //目标屏幕坐标+(定位点地图坐标-定位点屏幕坐标) |
| | | return screenCoordinate.Add(LocationDic[locationCoor.Parameter].Sub(locationCoor.Point)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 地图坐标转屏幕坐标 |
| | | /// </summary> |
| | | /// <param name="mapCoordinate"></param> |
| | | /// <param name="locationParameter"></param> |
| | | /// <param name="locationCoordinate"></param> |
| | | /// <returns></returns> |
| | | public ZTPoint MapToScreenCoordinate(ZTPoint mapCoordinate, ParametersPoint locationCoor) |
| | | { |
| | | if (!LocationDic.ContainsKey(locationCoor.Parameter)) |
| | | { |
| | | throw new ArgumentOutOfRangeException("不存在的定位点,parameter:" + locationCoor.Parameter.ToString()); |
| | | } |
| | | |
| | | //目标地图坐标-(定位点地图坐标-定位点屏幕坐标) |
| | | return mapCoordinate.Sub(LocationDic[locationCoor.Parameter].Sub(locationCoor.Point)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 两点之间寻路 |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="end"></param> |
| | | public List<ZTPoint> FindPath(ref ZTPoint start, ref ZTPoint end) |
| | | { |
| | | |
| | | if (start.Equals(end)) |
| | | { |
| | | return new List<ZTPoint>(); |
| | | } |
| | | |
| | | //查询两点间是否连通 |
| | | if (Iscross(start, end)) |
| | | { |
| | | //两点直接连通 |
| | | return new List<ZTPoint>() { end }; |
| | | } |
| | | |
| | | //确保两点不在障碍物里 |
| | | bool inObstacle = EnsureNotInObstacle(ref start); |
| | | inObstacle = EnsureNotInObstacle(ref end) || inObstacle; |
| | | |
| | | //查询两点间是否连通 |
| | | if (inObstacle && Iscross(start, end)) |
| | | { |
| | | //两点直接连通 |
| | | return new List<ZTPoint>() { end }; |
| | | } |
| | | |
| | | |
| | | //把两点添加到寻路网中 |
| | | AddConnectivityEdgeToFinder(start, end); |
| | | |
| | | //寻路,组合路径 |
| | | List<ZTPoint> paths = this.PathFinder.ShortestPath(start, end); |
| | | |
| | | //去除寻路网中 |
| | | RemoveStartAndEndVerticeFromFinder(start, end); |
| | | return paths; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查找到下一关进门点 |
| | | /// </summary> |
| | | /// <param name="rolePosition"></param> |
| | | /// <returns></returns> |
| | | public List<ZTPoint> FindDoorPath(out Int32 doorIndex,ZTPoint rolePosition) |
| | | { |
| | | doorIndex = 0; |
| | | ZTPoint end = this.HousePathInfo.NextGates[0].Point; |
| | | return FindPath(ref rolePosition, ref end); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断两点间是否连通 |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="end"></param> |
| | | /// <returns></returns> |
| | | private bool Iscross(ZTPoint start, ZTPoint end) |
| | | { |
| | | |
| | | for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++) |
| | | { |
| | | Intersection interSection = GeometryHelper.IntersectionOf(new ZTLinePoint(start, end), this.HousePathInfo.Obstacles[i]); |
| | | if (interSection != Intersection.None) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否在障碍物里,如果在障碍物里则返回最近的不在障碍物点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns>true:在障碍物,false:不在障碍物里</returns> |
| | | private bool EnsureNotInObstacle(ref ZTPoint point) |
| | | { |
| | | ZTPoint source = new ZTPoint(point.X, point.Y); |
| | | ZTPolygon obstacle = ZTPolygon.Empty; |
| | | for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++) |
| | | { |
| | | ZTPolygon temp = this.HousePathInfo.Obstacles[i]; |
| | | if (GeometryHelper.IntersectionOf(point, temp) != Intersection.None) |
| | | { |
| | | obstacle = this.HousePathInfo.Obstacles[i]; |
| | | break; |
| | | } |
| | | } |
| | | if (obstacle.Equals(ZTPolygon.Empty)) |
| | | { |
| | | //不在障碍物内 |
| | | return false; |
| | | } |
| | | |
| | | //计算距离障碍物外最近的距离 |
| | | double distance = 0; |
| | | ZTPoint lastPoint = ZTPoint.Empty; |
| | | for (int i = 0; i < obstacle.Points.Length; i++) |
| | | { |
| | | if (i == 0) |
| | | { |
| | | lastPoint = obstacle.Points[i]; |
| | | distance = GeometryHelper.GetPointDistance(lastPoint, point); |
| | | } |
| | | double lastDistance = GeometryHelper.GetNearestDistance(new ZTLinePoint(lastPoint, obstacle[i]), point); |
| | | if (lastDistance < distance) |
| | | { |
| | | distance = lastDistance; |
| | | } |
| | | if (distance <= 0) |
| | | { |
| | | distance = 0; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | //查找最近离开障碍物的点 |
| | | ZTPoint testPoint = new ZTPoint(point.X, point.Y); |
| | | Int32 maxDistance = Math.Max(Math.Max(point.X, this.HousePathInfo.Width - point.X), Math.Max(point.Y, this.HousePathInfo.Height - point.Y)); |
| | | for (int i = (Int32)distance; i < maxDistance; i++) |
| | | { |
| | | //下 |
| | | if (point.Y + i <= this.HousePathInfo.Height) |
| | | { |
| | | testPoint = new ZTPoint(point.X, point.Y + i); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.Y += 10; |
| | | point = testPoint; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | //右 |
| | | if (point.X <= this.HousePathInfo.Width) |
| | | { |
| | | testPoint = new ZTPoint(point.X + i, point.Y); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.X += 10; |
| | | point = testPoint; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | //左 |
| | | if (point.X - i >= 0) |
| | | { |
| | | testPoint = new ZTPoint(point.X - i, point.Y); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.X -= 10; |
| | | point = testPoint; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | //上 |
| | | if (point.Y - i >= 0) |
| | | { |
| | | testPoint = new ZTPoint(point.X, point.Y - i); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.Y -= 10; |
| | | point = testPoint; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 初始化寻路器 |
| | | /// </summary> |
| | | private void InitPathInfo() |
| | | { |
| | | this.PathFinder = new Dijkstra<ZTPoint>(); |
| | | |
| | | //添加寻路路径 |
| | | ZTLinePoint line; |
| | | for (int i = 0; i < this.HousePathInfo.FindPathLines.Count; i++) |
| | | { |
| | | line = this.HousePathInfo.FindPathLines[i]; |
| | | this.PathFinder.AddEdge(line.P1, line.P2, line.GetDistance()); |
| | | } |
| | | |
| | | |
| | | //定位点添加到字典 |
| | | for (int i = 0; i < this.HousePathInfo.LocationPoints.Count; i++) |
| | | { |
| | | ParametersPoint pp = this.HousePathInfo.LocationPoints[i]; |
| | | if (!this.LocationDic.ContainsKey(pp.Parameter)) |
| | | { |
| | | this.LocationDic.Add(pp.Parameter, pp.Point); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 向查找器中添加起点和终点可连通的边 |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="end"></param> |
| | | private void AddConnectivityEdgeToFinder(ZTPoint start, ZTPoint end) |
| | | { |
| | | Int32 distance = 0; |
| | | ZTPoint point; |
| | | for (int i = 0; i < this.HousePathInfo.FindPathPoints.Count; i++) |
| | | { |
| | | point = this.HousePathInfo.FindPathPoints[i]; |
| | | if (Iscross(start, point)) |
| | | { |
| | | distance = (Int32)GeometryHelper.GetPointDistance(start, point); |
| | | this.PathFinder.AddEdge(start, point, distance); |
| | | } |
| | | |
| | | if (Iscross(end, point)) |
| | | { |
| | | distance = (Int32)GeometryHelper.GetPointDistance(end, point); |
| | | this.PathFinder.AddEdge(end, point, distance); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 从查找器中移除起点和终点 |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="end"></param> |
| | | private void RemoveStartAndEndVerticeFromFinder(ZTPoint start, ZTPoint end) |
| | | { |
| | | this.PathFinder.RemoveEdge(start); |
| | | this.PathFinder.RemoveEdge(end); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.Utility.Utilitys; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Maps |
| | | { |
| | | /// <summary> |
| | | /// 路径信息 |
| | | /// </summary> |
| | | public class HousePathInfo |
| | | { |
| | | public HousePathInfo() |
| | | { |
| | | Obstacles = new List<ZTPolygon>(); |
| | | LocationPoints = new List<ParametersPoint>(); |
| | | FindPathPoints = new List<ZTPoint>(); |
| | | FindPathLines = new List<ZTLinePoint>(); |
| | | NextGates = new List<ParametersPoint>(); |
| | | PathGuides = new List<ZTTargetPolygon>(); |
| | | LoopPoint = new ZTPoint(); |
| | | } |
| | | |
| | | |
| | | |
| | | public HousePathInfo(Int32 width, Int32 height) : this() |
| | | { |
| | | this.Width = width; |
| | | this.Height = height; |
| | | } |
| | | |
| | | |
| | | #region Propertys |
| | | /// <summary> |
| | | /// 宽 |
| | | /// </summary> |
| | | public int Width { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 高 |
| | | /// </summary> |
| | | public int Height { get; set; } |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 障碍物 |
| | | /// </summary> |
| | | public List<ZTPolygon> Obstacles { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 定位点 |
| | | /// </summary> |
| | | public List<ParametersPoint> LocationPoints { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 寻路点 |
| | | /// </summary> |
| | | public List<ZTPoint> FindPathPoints { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 寻路线 |
| | | /// </summary> |
| | | public List<ZTLinePoint> FindPathLines { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 巡逻点 |
| | | /// </summary> |
| | | public ZTPoint LoopPoint { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 下一关进门点 |
| | | /// 参数意义 0:上 1:右 2:下 3:左 |
| | | /// </summary> |
| | | public List<ParametersPoint> NextGates { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 路径向导,把某一区域的点导向某一点 |
| | | /// </summary> |
| | | public List<ZTTargetPolygon> PathGuides { get; set; } |
| | | |
| | | #endregion |
| | | |
| | | |
| | | #region Editor |
| | | /// <summary> |
| | | /// 添加障碍物 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public bool AddObstacle(ZTPolygon obstacle) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsObstacle(out index, obstacle)) |
| | | { |
| | | return false; |
| | | } |
| | | this.Obstacles.Add(obstacle); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 删除障碍物 |
| | | /// </summary> |
| | | /// <param name="obstacle"></param> |
| | | /// <returns></returns> |
| | | public bool RemoveObstacle(ZTPolygon obstacle) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsObstacle(out index, obstacle)) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | this.Obstacles.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在障碍物 |
| | | /// </summary> |
| | | /// <param name="obstacle"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsObstacle(out Int32 index, ZTPolygon obstacle) |
| | | { |
| | | index = 0; |
| | | for (int i = 0; i < Obstacles.Count; i++) |
| | | { |
| | | if (Obstacles[i] .Equals( obstacle)) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 添加定位点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <param name="parameters"></param> |
| | | /// <returns></returns> |
| | | public bool AddLocationPosition(ParametersPoint point) |
| | | { |
| | | if (this.LocationPoints.Exists((p) => { return point.Point.Equals(p.Point); })) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.LocationPoints.Add(point); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 清空定位点 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public void ClearLocationPosiltion() |
| | | { |
| | | this.LocationPoints.Clear(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 添加寻路点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public bool AddFindPathPoint(ZTPoint point) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsFindPathPoint(out index, point)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.FindPathPoints.Add(point); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 删除寻路点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public bool RemoveFindPathPoint(ZTPoint point) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsFindPathPoint(out index, point)) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | //查询巡逻线和寻路线是否有用到此点 |
| | | if (ExistsPointInAllLine(point)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.FindPathPoints.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在指定寻路点 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsFindPathPoint(out Int32 index, ZTPoint point) |
| | | { |
| | | index = 0; |
| | | for (int i = 0; i < this.FindPathPoints.Count; i++) |
| | | { |
| | | if (this.FindPathPoints[i].Equals(point)) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 添加寻路线 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | public bool AddFindPathLine(ZTLinePoint line) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsFindPathLine(out index, line)) |
| | | { |
| | | return false; |
| | | } |
| | | this.FindPathLines.Add(line); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 删除寻路线 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | public bool RemoveFindPathLine(ZTLinePoint line) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsFindPathLine(out index, line)) |
| | | { |
| | | return true; |
| | | } |
| | | this.FindPathLines.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 是否存在寻路线 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsFindPathLine(out Int32 index, ZTLinePoint line) |
| | | { |
| | | index = 0; |
| | | for (int i = 0; i < this.FindPathLines.Count; i++) |
| | | { |
| | | if (this.FindPathLines[i] .Equals( line)) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 巡逻线或寻路线中是否存在某点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsPointInAllLine(ZTPoint point) |
| | | { |
| | | for (int i = 0; i < this.FindPathLines.Count; i++) |
| | | { |
| | | if (this.FindPathLines[i].P1.Equals(point) || this.FindPathLines[i].P2.Equals(point)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加下一关的门 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public bool AddNextGate(ParametersPoint point) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsNextGate(out index, point)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.NextGates.Add(point); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移除下一关的门 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public bool RemoveNextGate(ParametersPoint point) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsNextGate(out index, point)) |
| | | { |
| | | return true; |
| | | } |
| | | this.NextGates.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在到达下一关的点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public bool ExistsNextGate(out Int32 index,ParametersPoint point) |
| | | { |
| | | index = -1; |
| | | for (int i = 0; i < this.NextGates.Count; i++) |
| | | { |
| | | if (this.NextGates.Equals(point)) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加路径导引多边形 |
| | | /// </summary> |
| | | /// <param name="polygon"></param> |
| | | /// <returns></returns> |
| | | public bool AddPathGuide(ZTTargetPolygon polygon) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsPathGuide(out index, polygon)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.PathGuides.Add(polygon); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 移除路径导引多边形 |
| | | /// </summary> |
| | | /// <param name="polygon"></param> |
| | | /// <returns></returns> |
| | | public bool RemovePathGuide(ZTTargetPolygon polygon) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsPathGuide(out index, polygon)) |
| | | { |
| | | return true; |
| | | } |
| | | this.PathGuides.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在路径导引 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <param name="polygon"></param> |
| | | /// <returns></returns> |
| | | public bool ExistsPathGuide(out Int32 index, ZTTargetPolygon polygon) |
| | | { |
| | | index = -1; |
| | | for (int i = 0; i < this.PathGuides.Count; i++) |
| | | { |
| | | if (this.PathGuides.Equals(polygon)) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | |
| | | #region json info |
| | | //凛冬 |
| | | private static readonly string[] Lingdong = new string[] { |
| | | //0 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //1 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //2 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //3 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //4 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //5 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //6 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //7 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //8 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //9 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //10 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //11 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //12 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //13 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //14 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //15 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //16 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //17 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //18 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //19 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}" |
| | | }; |
| | | |
| | | |
| | | //卡勒特 |
| | | private static readonly string[] Kalete = new string[] { |
| | | //0: |
| | | "{\"Width\":896,\"Height\":686,\"Obstacles\":[{\"Points\":[{\"X\":2,\"Y\":320},{\"X\":460,\"Y\":310},{\"X\":493,\"Y\":319},{\"X\":556,\"Y\":334},{\"X\":668,\"Y\":344},{\"X\":759,\"Y\":330},{\"X\":873,\"Y\":308},{\"X\":893,\"Y\":300},{\"X\":891,\"Y\":1},{\"X\":2,\"Y\":3}],\"Length\":10},{\"Points\":[{\"X\":2,\"Y\":552},{\"X\":71,\"Y\":545},{\"X\":76,\"Y\":427},{\"X\":165,\"Y\":439},{\"X\":166,\"Y\":521},{\"X\":253,\"Y\":559},{\"X\":703,\"Y\":550},{\"X\":703,\"Y\":521},{\"X\":823,\"Y\":513},{\"X\":834,\"Y\":568},{\"X\":893,\"Y\":559},{\"X\":893,\"Y\":684},{\"X\":4,\"Y\":683}],\"Length\":13}],\"LocationPoints\":[{\"Point\":{\"X\":797,\"Y\":348},\"Parameter\":0},{\"Point\":{\"X\":671,\"Y\":348},\"Parameter\":1},{\"Point\":{\"X\":547,\"Y\":348},\"Parameter\":2},{\"Point\":{\"X\":423,\"Y\":348},\"Parameter\":3},{\"Point\":{\"X\":298,\"Y\":347},\"Parameter\":4},{\"Point\":{\"X\":172,\"Y\":348},\"Parameter\":5},{\"Point\":{\"X\":47,\"Y\":348},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":51,\"Y\":392},{\"X\":438,\"Y\":418},{\"X\":775,\"Y\":400}],\"LoopLines\":[],\"FindPathLines\":[{\"P1\":{\"X\":51,\"Y\":392},\"P2\":{\"X\":775,\"Y\":400}},{\"P1\":{\"X\":438,\"Y\":418},\"P2\":{\"X\":775,\"Y\":400}},{\"P1\":{\"X\":438,\"Y\":418},\"P2\":{\"X\":51,\"Y\":392}}],\"NextGates\":[{\"Point\":{\"X\":778,\"Y\":346},\"Parameter\":1}],\"PathGuides\":[]}", |
| | | //1: |
| | | "{\"Width\":1349,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":124,\"Y\":324},{\"X\":760,\"Y\":310},{\"X\":956,\"Y\":414},{\"X\":1124,\"Y\":372},{\"X\":1113,\"Y\":301},{\"X\":1346,\"Y\":297},{\"X\":1345,\"Y\":3},{\"X\":0,\"Y\":2},{\"X\":0,\"Y\":375}],\"Length\":9},{\"Points\":[{\"X\":1342,\"Y\":675},{\"X\":1189,\"Y\":675},{\"X\":1191,\"Y\":713},{\"X\":949,\"Y\":712},{\"X\":867,\"Y\":772},{\"X\":840,\"Y\":897},{\"X\":1345,\"Y\":899}],\"Length\":7},{\"Points\":[{\"X\":651,\"Y\":668},{\"X\":459,\"Y\":671},{\"X\":446,\"Y\":641},{\"X\":247,\"Y\":641},{\"X\":236,\"Y\":608},{\"X\":155,\"Y\":612},{\"X\":150,\"Y\":549},{\"X\":295,\"Y\":541},{\"X\":376,\"Y\":557},{\"X\":472,\"Y\":592},{\"X\":473,\"Y\":609},{\"X\":627,\"Y\":606}],\"Length\":12},{\"Points\":[{\"X\":565,\"Y\":815},{\"X\":464,\"Y\":737},{\"X\":0,\"Y\":721},{\"X\":1,\"Y\":896},{\"X\":839,\"Y\":894},{\"X\":851,\"Y\":815}],\"Length\":6}],\"LocationPoints\":[{\"Point\":{\"X\":270,\"Y\":462},\"Parameter\":0},{\"Point\":{\"X\":732,\"Y\":461},\"Parameter\":1},{\"Point\":{\"X\":1192,\"Y\":461},\"Parameter\":2},{\"Point\":{\"X\":708,\"Y\":344},\"Parameter\":8},{\"Point\":{\"X\":706,\"Y\":197},\"Parameter\":9},{\"Point\":{\"X\":706,\"Y\":53},\"Parameter\":10}],\"FindPathPoints\":[{\"X\":1211,\"Y\":323},{\"X\":193,\"Y\":419},{\"X\":1251,\"Y\":446},{\"X\":746,\"Y\":498},{\"X\":769,\"Y\":657},{\"X\":111,\"Y\":660}],\"LoopLines\":[{\"P1\":{\"X\":193,\"Y\":419},\"P2\":{\"X\":1251,\"Y\":446}}],\"FindPathLines\":[{\"P1\":{\"X\":193,\"Y\":419},\"P2\":{\"X\":746,\"Y\":498}},{\"P1\":{\"X\":746,\"Y\":498},\"P2\":{\"X\":1251,\"Y\":446}},{\"P1\":{\"X\":746,\"Y\":498},\"P2\":{\"X\":769,\"Y\":657}},{\"P1\":{\"X\":769,\"Y\":657},\"P2\":{\"X\":1251,\"Y\":446}},{\"P1\":{\"X\":769,\"Y\":657},\"P2\":{\"X\":193,\"Y\":419}},{\"P1\":{\"X\":1251,\"Y\":446},\"P2\":{\"X\":1211,\"Y\":323}},{\"P1\":{\"X\":769,\"Y\":657},\"P2\":{\"X\":1211,\"Y\":323}},{\"P1\":{\"X\":111,\"Y\":660},\"P2\":{\"X\":193,\"Y\":419}},{\"P1\":{\"X\":111,\"Y\":660},\"P2\":{\"X\":769,\"Y\":657}}]}", |
| | | string.Empty,//2 |
| | | //3: |
| | | "{\"Width\":1348,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":0,\"Y\":313},{\"X\":927,\"Y\":295},{\"X\":963,\"Y\":334},{\"X\":1275,\"Y\":314},{\"X\":1343,\"Y\":300},{\"X\":1343,\"Y\":2},{\"X\":1,\"Y\":1}],\"Length\":7},{\"Points\":[{\"X\":878,\"Y\":366},{\"X\":750,\"Y\":369},{\"X\":733,\"Y\":354},{\"X\":740,\"Y\":325},{\"X\":876,\"Y\":324}],\"Length\":5},{\"Points\":[{\"X\":1345,\"Y\":551},{\"X\":1170,\"Y\":587},{\"X\":1173,\"Y\":643},{\"X\":1275,\"Y\":713},{\"X\":1346,\"Y\":706}],\"Length\":5},{\"Points\":[{\"X\":285,\"Y\":307},{\"X\":312,\"Y\":576},{\"X\":195,\"Y\":626},{\"X\":208,\"Y\":691},{\"X\":153,\"Y\":723},{\"X\":150,\"Y\":897},{\"X\":2,\"Y\":896},{\"X\":0,\"Y\":319}],\"Length\":8},{\"Points\":[{\"X\":156,\"Y\":752},{\"X\":369,\"Y\":714},{\"X\":793,\"Y\":734},{\"X\":932,\"Y\":822},{\"X\":1032,\"Y\":814},{\"X\":1058,\"Y\":896},{\"X\":159,\"Y\":894}],\"Length\":7},{\"Points\":[{\"X\":1037,\"Y\":824},{\"X\":1243,\"Y\":820},{\"X\":1229,\"Y\":748},{\"X\":1269,\"Y\":718},{\"X\":1344,\"Y\":709},{\"X\":1345,\"Y\":896},{\"X\":1064,\"Y\":897}],\"Length\":7}],\"LocationPoints\":[{\"Point\":{\"X\":1108,\"Y\":329},\"Parameter\":8},{\"Point\":{\"X\":1107,\"Y\":182},\"Parameter\":9},{\"Point\":{\"X\":1107,\"Y\":37},\"Parameter\":10}],\"FindPathPoints\":[{\"X\":358,\"Y\":342},{\"X\":378,\"Y\":505},{\"X\":1270,\"Y\":415},{\"X\":1038,\"Y\":650}],\"LoopLines\":[{\"P1\":{\"X\":358,\"Y\":342},\"P2\":{\"X\":1038,\"Y\":650}}],\"FindPathLines\":[{\"P1\":{\"X\":358,\"Y\":342},\"P2\":{\"X\":1270,\"Y\":415}},{\"P1\":{\"X\":1270,\"Y\":415},\"P2\":{\"X\":1038,\"Y\":650}},{\"P1\":{\"X\":1270,\"Y\":415},\"P2\":{\"X\":378,\"Y\":505}},{\"P1\":{\"X\":378,\"Y\":505},\"P2\":{\"X\":358,\"Y\":342}},{\"P1\":{\"X\":378,\"Y\":505},\"P2\":{\"X\":1038,\"Y\":650}}]}", |
| | | string.Empty,//4 |
| | | string.Empty,//5 |
| | | //6: |
| | | "{\"Width\":1350,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":325,\"Y\":425},{\"X\":437,\"Y\":447},{\"X\":567,\"Y\":437},{\"X\":565,\"Y\":395},{\"X\":631,\"Y\":398},{\"X\":675,\"Y\":410},{\"X\":809,\"Y\":405},{\"X\":810,\"Y\":375},{\"X\":933,\"Y\":329},{\"X\":1279,\"Y\":303},{\"X\":1345,\"Y\":367},{\"X\":1345,\"Y\":5},{\"X\":1,\"Y\":6}],\"Length\":13},{\"Points\":[{\"X\":1347,\"Y\":481},{\"X\":1246,\"Y\":501},{\"X\":1235,\"Y\":551},{\"X\":1188,\"Y\":617},{\"X\":1192,\"Y\":669},{\"X\":1348,\"Y\":673}],\"Length\":6},{\"Points\":[{\"X\":1349,\"Y\":701},{\"X\":791,\"Y\":719},{\"X\":803,\"Y\":659},{\"X\":396,\"Y\":665},{\"X\":361,\"Y\":723},{\"X\":2,\"Y\":711},{\"X\":0,\"Y\":896},{\"X\":1345,\"Y\":898}],\"Length\":8}],\"LocationPoints\":[{\"Point\":{\"X\":1080,\"Y\":425},\"Parameter\":4},{\"Point\":{\"X\":592,\"Y\":427},\"Parameter\":5},{\"Point\":{\"X\":103,\"Y\":427},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":174,\"Y\":537},{\"X\":1197,\"Y\":430},{\"X\":602,\"Y\":502}],\"LoopLines\":[{\"P1\":{\"X\":174,\"Y\":537},\"P2\":{\"X\":1197,\"Y\":430}}],\"FindPathLines\":[{\"P1\":{\"X\":174,\"Y\":537},\"P2\":{\"X\":602,\"Y\":502}},{\"P1\":{\"X\":602,\"Y\":502},\"P2\":{\"X\":1197,\"Y\":430}}]}", |
| | | //7: |
| | | "{\"Width\":1350,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":31,\"Y\":409},{\"X\":127,\"Y\":312},{\"X\":505,\"Y\":351},{\"X\":570,\"Y\":394},{\"X\":733,\"Y\":418},{\"X\":888,\"Y\":410},{\"X\":896,\"Y\":334},{\"X\":1066,\"Y\":328},{\"X\":1100,\"Y\":401},{\"X\":1315,\"Y\":425},{\"X\":1349,\"Y\":427},{\"X\":1343,\"Y\":1},{\"X\":4,\"Y\":4},{\"X\":1,\"Y\":341}],\"Length\":14},{\"Points\":[{\"X\":467,\"Y\":896},{\"X\":472,\"Y\":733},{\"X\":325,\"Y\":676},{\"X\":178,\"Y\":636},{\"X\":0,\"Y\":625},{\"X\":2,\"Y\":900}],\"Length\":6}],\"LocationPoints\":[{\"Point\":{\"X\":270,\"Y\":462},\"Parameter\":0},{\"Point\":{\"X\":730,\"Y\":463},\"Parameter\":1},{\"Point\":{\"X\":1191,\"Y\":463},\"Parameter\":2},{\"Point\":{\"X\":1078,\"Y\":499},\"Parameter\":4},{\"Point\":{\"X\":589,\"Y\":497},\"Parameter\":5},{\"Point\":{\"X\":100,\"Y\":498},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":146,\"Y\":440},{\"X\":1226,\"Y\":720}],\"LoopLines\":[{\"P1\":{\"X\":146,\"Y\":440},\"P2\":{\"X\":1226,\"Y\":720}}],\"FindPathLines\":[]}", |
| | | //8: |
| | | "{\"Width\":1686,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":2,\"Y\":420},{\"X\":130,\"Y\":439},{\"X\":311,\"Y\":462},{\"X\":313,\"Y\":400},{\"X\":221,\"Y\":319},{\"X\":453,\"Y\":288},{\"X\":632,\"Y\":5},{\"X\":4,\"Y\":2}],\"Length\":8},{\"Points\":[{\"X\":574,\"Y\":104},{\"X\":743,\"Y\":319},{\"X\":961,\"Y\":306},{\"X\":1014,\"Y\":343},{\"X\":1099,\"Y\":326},{\"X\":1165,\"Y\":369},{\"X\":1534,\"Y\":365},{\"X\":1684,\"Y\":309},{\"X\":1680,\"Y\":4},{\"X\":633,\"Y\":5}],\"Length\":10},{\"Points\":[{\"X\":1682,\"Y\":470},{\"X\":1540,\"Y\":514},{\"X\":1442,\"Y\":590},{\"X\":1173,\"Y\":641},{\"X\":858,\"Y\":670},{\"X\":814,\"Y\":708},{\"X\":1681,\"Y\":715}],\"Length\":7}],\"LocationPoints\":[{\"Point\":{\"X\":277,\"Y\":501},\"Parameter\":0},{\"Point\":{\"X\":735,\"Y\":502},\"Parameter\":1},{\"Point\":{\"X\":1196,\"Y\":502},\"Parameter\":2},{\"Point\":{\"X\":1418,\"Y\":390},\"Parameter\":4},{\"Point\":{\"X\":930,\"Y\":387},\"Parameter\":5},{\"Point\":{\"X\":441,\"Y\":388},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":186,\"Y\":483},{\"X\":1565,\"Y\":393},{\"X\":549,\"Y\":448}],\"LoopLines\":[{\"P1\":{\"X\":186,\"Y\":483},\"P2\":{\"X\":1565,\"Y\":393}}],\"FindPathLines\":[{\"P1\":{\"X\":186,\"Y\":483},\"P2\":{\"X\":549,\"Y\":448}},{\"P1\":{\"X\":549,\"Y\":448},\"P2\":{\"X\":1565,\"Y\":393}}]}", |
| | | //9: |
| | | "{\"Width\":1688,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":3,\"Y\":333},{\"X\":390,\"Y\":305},{\"X\":600,\"Y\":389},{\"X\":746,\"Y\":389},{\"X\":766,\"Y\":327},{\"X\":890,\"Y\":334},{\"X\":914,\"Y\":247},{\"X\":1092,\"Y\":225},{\"X\":1305,\"Y\":396},{\"X\":1489,\"Y\":346},{\"X\":1684,\"Y\":411},{\"X\":1683,\"Y\":3},{\"X\":3,\"Y\":3}],\"Length\":13},{\"Points\":[{\"X\":389,\"Y\":671},{\"X\":398,\"Y\":614},{\"X\":868,\"Y\":605},{\"X\":1037,\"Y\":631},{\"X\":1125,\"Y\":589},{\"X\":1536,\"Y\":632},{\"X\":1678,\"Y\":682},{\"X\":1682,\"Y\":715},{\"X\":378,\"Y\":715}],\"Length\":9}],\"LocationPoints\":[{\"Point\":{\"X\":274,\"Y\":500},\"Parameter\":0},{\"Point\":{\"X\":738,\"Y\":502},\"Parameter\":1},{\"Point\":{\"X\":1200,\"Y\":501},\"Parameter\":2},{\"Point\":{\"X\":1658,\"Y\":503},\"Parameter\":3}],\"FindPathPoints\":[{\"X\":216,\"Y\":456},{\"X\":1545,\"Y\":466},{\"X\":985,\"Y\":515}],\"LoopLines\":[{\"P1\":{\"X\":216,\"Y\":456},\"P2\":{\"X\":1545,\"Y\":466}}],\"FindPathLines\":[{\"P1\":{\"X\":216,\"Y\":456},\"P2\":{\"X\":985,\"Y\":515}},{\"P1\":{\"X\":985,\"Y\":515},\"P2\":{\"X\":1545,\"Y\":466}}]}", |
| | | string.Empty,//10 |
| | | //11: |
| | | "{\"Width\":1686,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":1678,\"Y\":410},{\"X\":1576,\"Y\":341},{\"X\":1258,\"Y\":344},{\"X\":1241,\"Y\":379},{\"X\":1153,\"Y\":380},{\"X\":849,\"Y\":377},{\"X\":765,\"Y\":353},{\"X\":598,\"Y\":352},{\"X\":498,\"Y\":387},{\"X\":0,\"Y\":360},{\"X\":1,\"Y\":1},{\"X\":1681,\"Y\":2}],\"Length\":12},{\"Points\":[{\"X\":1566,\"Y\":714},{\"X\":1502,\"Y\":662},{\"X\":875,\"Y\":654},{\"X\":780,\"Y\":660},{\"X\":550,\"Y\":636},{\"X\":365,\"Y\":614},{\"X\":183,\"Y\":626},{\"X\":72,\"Y\":636},{\"X\":10,\"Y\":655},{\"X\":0,\"Y\":715}],\"Length\":10}],\"LocationPoints\":[{\"Point\":{\"X\":929,\"Y\":450},\"Parameter\":5},{\"Point\":{\"X\":440,\"Y\":452},\"Parameter\":6},{\"Point\":{\"X\":1416,\"Y\":451},\"Parameter\":4}],\"FindPathPoints\":[{\"X\":71,\"Y\":469},{\"X\":1529,\"Y\":462},{\"X\":826,\"Y\":576}],\"LoopLines\":[{\"P1\":{\"X\":71,\"Y\":469},\"P2\":{\"X\":1529,\"Y\":462}}],\"FindPathLines\":[{\"P1\":{\"X\":71,\"Y\":469},\"P2\":{\"X\":826,\"Y\":576}},{\"P1\":{\"X\":826,\"Y\":576},\"P2\":{\"X\":1529,\"Y\":462}}]}", |
| | | //12: |
| | | "{\"Width\":2024,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":795,\"Y\":351},{\"X\":1897,\"Y\":323},{\"X\":2019,\"Y\":271},{\"X\":2019,\"Y\":4},{\"X\":1,\"Y\":2},{\"X\":3,\"Y\":347},{\"X\":111,\"Y\":400},{\"X\":200,\"Y\":377},{\"X\":294,\"Y\":344},{\"X\":560,\"Y\":351},{\"X\":623,\"Y\":381}],\"Length\":11},{\"Points\":[{\"X\":2020,\"Y\":614},{\"X\":1464,\"Y\":615},{\"X\":1137,\"Y\":589},{\"X\":895,\"Y\":606},{\"X\":855,\"Y\":715},{\"X\":2020,\"Y\":716}],\"Length\":6},{\"Points\":[{\"X\":525,\"Y\":715},{\"X\":451,\"Y\":589},{\"X\":156,\"Y\":603},{\"X\":2,\"Y\":495},{\"X\":2,\"Y\":716}],\"Length\":5}],\"LocationPoints\":[{\"Point\":{\"X\":270,\"Y\":461},\"Parameter\":0},{\"Point\":{\"X\":731,\"Y\":461},\"Parameter\":1},{\"Point\":{\"X\":1192,\"Y\":462},\"Parameter\":2},{\"Point\":{\"X\":1650,\"Y\":463},\"Parameter\":3},{\"Point\":{\"X\":1278,\"Y\":347},\"Parameter\":5},{\"Point\":{\"X\":788,\"Y\":347},\"Parameter\":6},{\"Point\":{\"X\":301,\"Y\":346},\"Parameter\":7},{\"Point\":{\"X\":628,\"Y\":175},\"Parameter\":8},{\"Point\":{\"X\":627,\"Y\":28},\"Parameter\":9}],\"FindPathPoints\":[{\"X\":201,\"Y\":457},{\"X\":1894,\"Y\":423},{\"X\":699,\"Y\":513}],\"LoopLines\":[{\"P1\":{\"X\":201,\"Y\":457},\"P2\":{\"X\":1894,\"Y\":423}}],\"FindPathLines\":[{\"P1\":{\"X\":201,\"Y\":457},\"P2\":{\"X\":699,\"Y\":513}},{\"P1\":{\"X\":699,\"Y\":513},\"P2\":{\"X\":1894,\"Y\":423}}]}", |
| | | //13: |
| | | "{\"Width\":2024,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":1607,\"Y\":189},{\"X\":1761,\"Y\":360},{\"X\":2022,\"Y\":405},{\"X\":2022,\"Y\":1},{\"X\":1565,\"Y\":1}],\"Length\":5},{\"Points\":[{\"X\":1350,\"Y\":400},{\"X\":1605,\"Y\":186},{\"X\":1562,\"Y\":1},{\"X\":121,\"Y\":1},{\"X\":335,\"Y\":410},{\"X\":385,\"Y\":402}],\"Length\":6},{\"Points\":[{\"X\":2017,\"Y\":719},{\"X\":1228,\"Y\":729},{\"X\":1137,\"Y\":666},{\"X\":667,\"Y\":689},{\"X\":417,\"Y\":671},{\"X\":123,\"Y\":649},{\"X\":121,\"Y\":891},{\"X\":2020,\"Y\":896}],\"Length\":8},{\"Points\":[{\"X\":294,\"Y\":564},{\"X\":121,\"Y\":566},{\"X\":122,\"Y\":19},{\"X\":322,\"Y\":394},{\"X\":233,\"Y\":457}],\"Length\":5},{\"Points\":[{\"X\":1,\"Y\":2},{\"X\":127,\"Y\":3},{\"X\":128,\"Y\":896},{\"X\":0,\"Y\":894}],\"Length\":4}],\"LocationPoints\":[{\"Point\":{\"X\":537,\"Y\":496},\"Parameter\":0},{\"Point\":{\"X\":997,\"Y\":497},\"Parameter\":1},{\"Point\":{\"X\":1458,\"Y\":497},\"Parameter\":2},{\"Point\":{\"X\":1918,\"Y\":496},\"Parameter\":3},{\"Point\":{\"X\":777,\"Y\":484},\"Parameter\":6},{\"Point\":{\"X\":1266,\"Y\":484},\"Parameter\":5},{\"Point\":{\"X\":1753,\"Y\":485},\"Parameter\":4}],\"FindPathPoints\":[{\"X\":425,\"Y\":495},{\"X\":1885,\"Y\":496},{\"X\":1294,\"Y\":541}],\"LoopLines\":[{\"P1\":{\"X\":425,\"Y\":495},\"P2\":{\"X\":1885,\"Y\":496}}],\"FindPathLines\":[{\"P1\":{\"X\":425,\"Y\":495},\"P2\":{\"X\":1294,\"Y\":541}},{\"P1\":{\"X\":1294,\"Y\":541},\"P2\":{\"X\":1885,\"Y\":496}}]}", |
| | | //14: |
| | | "{\"Width\":1687,\"Height\":901,\"Obstacles\":[{\"Points\":[{\"X\":98,\"Y\":310},{\"X\":408,\"Y\":314},{\"X\":418,\"Y\":425},{\"X\":530,\"Y\":416},{\"X\":593,\"Y\":451},{\"X\":721,\"Y\":452},{\"X\":762,\"Y\":449},{\"X\":783,\"Y\":337},{\"X\":840,\"Y\":302},{\"X\":1207,\"Y\":300},{\"X\":1239,\"Y\":321},{\"X\":1418,\"Y\":320},{\"X\":1584,\"Y\":378},{\"X\":1679,\"Y\":377},{\"X\":1681,\"Y\":4},{\"X\":4,\"Y\":4},{\"X\":0,\"Y\":436}],\"Length\":17},{\"Points\":[{\"X\":1681,\"Y\":717},{\"X\":1319,\"Y\":706},{\"X\":1165,\"Y\":653},{\"X\":1053,\"Y\":654},{\"X\":835,\"Y\":609},{\"X\":732,\"Y\":624},{\"X\":680,\"Y\":667},{\"X\":0,\"Y\":650},{\"X\":0,\"Y\":898},{\"X\":1682,\"Y\":898}],\"Length\":10}],\"LocationPoints\":[{\"Point\":{\"X\":278,\"Y\":481},\"Parameter\":0},{\"Point\":{\"X\":739,\"Y\":481},\"Parameter\":1},{\"Point\":{\"X\":1200,\"Y\":479},\"Parameter\":2},{\"Point\":{\"X\":1656,\"Y\":480},\"Parameter\":3}],\"FindPathPoints\":[{\"X\":140,\"Y\":474},{\"X\":1453,\"Y\":466},{\"X\":763,\"Y\":520},{\"X\":373,\"Y\":565}],\"LoopLines\":[{\"P1\":{\"X\":140,\"Y\":474},\"P2\":{\"X\":1453,\"Y\":466}}],\"FindPathLines\":[{\"P1\":{\"X\":140,\"Y\":474},\"P2\":{\"X\":373,\"Y\":565}},{\"P1\":{\"X\":140,\"Y\":474},\"P2\":{\"X\":763,\"Y\":520}},{\"P1\":{\"X\":373,\"Y\":565},\"P2\":{\"X\":763,\"Y\":520}},{\"P1\":{\"X\":763,\"Y\":520},\"P2\":{\"X\":1453,\"Y\":466}},{\"P1\":{\"X\":373,\"Y\":565},\"P2\":{\"X\":1453,\"Y\":466}}]}", |
| | | string.Empty,//15 |
| | | //16: |
| | | "{\"Width\":1687,\"Height\":901,\"Obstacles\":[{\"Points\":[{\"X\":3,\"Y\":385},{\"X\":257,\"Y\":388},{\"X\":655,\"Y\":320},{\"X\":711,\"Y\":264},{\"X\":1682,\"Y\":279},{\"X\":1682,\"Y\":1},{\"X\":0,\"Y\":4}],\"Length\":7},{\"Points\":[{\"X\":5,\"Y\":713},{\"X\":265,\"Y\":754},{\"X\":432,\"Y\":862},{\"X\":405,\"Y\":900},{\"X\":1,\"Y\":896}],\"Length\":5},{\"Points\":[{\"X\":720,\"Y\":883},{\"X\":825,\"Y\":776},{\"X\":1034,\"Y\":851},{\"X\":985,\"Y\":900},{\"X\":712,\"Y\":900}],\"Length\":5},{\"Points\":[{\"X\":1173,\"Y\":871},{\"X\":1569,\"Y\":644},{\"X\":1674,\"Y\":661},{\"X\":1684,\"Y\":772},{\"X\":1679,\"Y\":887},{\"X\":1187,\"Y\":893},{\"X\":1200,\"Y\":852}],\"Length\":7}],\"LocationPoints\":[{\"Point\":{\"X\":1391,\"Y\":410},\"Parameter\":4},{\"Point\":{\"X\":905,\"Y\":409},\"Parameter\":5},{\"Point\":{\"X\":416,\"Y\":410},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":633,\"Y\":693},{\"X\":1494,\"Y\":434},{\"X\":139,\"Y\":505},{\"X\":834,\"Y\":367}],\"LoopLines\":[{\"P1\":{\"X\":139,\"Y\":505},\"P2\":{\"X\":1494,\"Y\":434}}],\"FindPathLines\":[{\"P1\":{\"X\":139,\"Y\":505},\"P2\":{\"X\":834,\"Y\":367}},{\"P1\":{\"X\":834,\"Y\":367},\"P2\":{\"X\":1494,\"Y\":434}},{\"P1\":{\"X\":633,\"Y\":693},\"P2\":{\"X\":1494,\"Y\":434}},{\"P1\":{\"X\":633,\"Y\":693},\"P2\":{\"X\":834,\"Y\":367}},{\"P1\":{\"X\":633,\"Y\":693},\"P2\":{\"X\":139,\"Y\":505}}]}", |
| | | //17: |
| | | "{\"Width\":1687,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":1681,\"Y\":368},{\"X\":1591,\"Y\":363},{\"X\":1487,\"Y\":252},{\"X\":1475,\"Y\":4},{\"X\":1683,\"Y\":3}],\"Length\":5},{\"Points\":[{\"X\":1348,\"Y\":358},{\"X\":544,\"Y\":345},{\"X\":534,\"Y\":453},{\"X\":115,\"Y\":450},{\"X\":0,\"Y\":390},{\"X\":0,\"Y\":3},{\"X\":1480,\"Y\":3},{\"X\":1487,\"Y\":245}],\"Length\":8},{\"Points\":[{\"X\":108,\"Y\":685},{\"X\":76,\"Y\":720},{\"X\":1682,\"Y\":718},{\"X\":1684,\"Y\":683}],\"Length\":4}],\"LocationPoints\":[{\"Point\":{\"X\":276,\"Y\":499},\"Parameter\":0},{\"Point\":{\"X\":736,\"Y\":502},\"Parameter\":1},{\"Point\":{\"X\":1198,\"Y\":500},\"Parameter\":2},{\"Point\":{\"X\":1655,\"Y\":502},\"Parameter\":3}],\"FindPathPoints\":[{\"X\":196,\"Y\":514},{\"X\":1622,\"Y\":491},{\"X\":605,\"Y\":518}],\"LoopLines\":[{\"P1\":{\"X\":196,\"Y\":514},\"P2\":{\"X\":1622,\"Y\":491}}],\"FindPathLines\":[{\"P1\":{\"X\":196,\"Y\":514},\"P2\":{\"X\":605,\"Y\":518}},{\"P1\":{\"X\":605,\"Y\":518},\"P2\":{\"X\":1622,\"Y\":491}}]}", |
| | | }; |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 获取json |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public string ToJsonString() |
| | | { |
| | | HousePathInfoObj obj=HousePathInfoObj.From(this); |
| | | string json = ZTImage.Json.JsonBuilder.ToJsonString(obj); |
| | | return json; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 从json字符串生成对象 |
| | | /// </summary> |
| | | /// <param name="json"></param> |
| | | /// <returns></returns> |
| | | public static HousePathInfo FromJsonString(string json) |
| | | { |
| | | HousePathInfoObj obj= ZTImage.Json.JsonParser.ToObject<HousePathInfoObj>(json); |
| | | return obj.To(); |
| | | } |
| | | |
| | | public static HousePathInfo From(MapType mapType, Int32 houseIndex) |
| | | { |
| | | string info = null; |
| | | if (mapType == MapType.Lingdong) |
| | | { |
| | | if (houseIndex > Lingdong.Length - 1) |
| | | { |
| | | throw new ArgumentOutOfRangeException("houseIndex"); |
| | | } |
| | | info = Lingdong[houseIndex]; |
| | | } |
| | | else if (mapType == MapType.Kalete) |
| | | { |
| | | if (houseIndex > Kalete.Length - 1) |
| | | { |
| | | throw new ArgumentOutOfRangeException("houseIndex"); |
| | | } |
| | | info = Kalete[houseIndex]; |
| | | } |
| | | |
| | | try |
| | | { |
| | | return HousePathInfo.FromJsonString(info); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw e; |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Maps |
| | | { |
| | | public enum MapType:Int32 |
| | | { |
| | | Lingdong =0,//凛冬 |
| | | Kalete,//卡勒特 |
| | | SkillSetting,//技能设置 |
| | | Test,//测试 |
| | | TestSpeed,//测速 |
| | | TestSkill,//测技能 |
| | | ReadRolePosition,//读取角色位置 |
| | | TestToNextDoor,//测试进入下一关的门 |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Maps |
| | | { |
| | | |
| | | |
| | | /// <summary> |
| | | /// 移动优化级 |
| | | /// </summary> |
| | | public enum MovePriority |
| | | { |
| | | Quantity,//数量集中为高优先级 |
| | | Nearly//近为高优先级 |
| | | } |
| | | } |
| | |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.Utility.Utilitys; |
| | | using System; |
| | | using System.Collections.Generic; |
| | |
| | | /// </summary> |
| | | public class DNFPathFinding |
| | | { |
| | | |
| | | public DNFPathFinding(HousePathInfo houseInfo) |
| | | { |
| | | this.HouseInfo = houseInfo; |
| | | this.HousePathInfo = houseInfo; |
| | | InitPathFinder(); |
| | | } |
| | | |
| | | public DNFPathFinding(MapType mapType, Int32 houseIndex) |
| | | { |
| | | if (houseIndex < 0) |
| | | { |
| | | throw new ArgumentOutOfRangeException("houseIndex"); |
| | | } |
| | | string info = null; |
| | | if (mapType == MapType.Lingdong) |
| | | { |
| | | if (houseIndex > Lingdong.Length - 1) |
| | | { |
| | | throw new ArgumentOutOfRangeException("houseIndex"); |
| | | } |
| | | info = Lingdong[houseIndex]; |
| | | } |
| | | else if (mapType == MapType.Kalete) |
| | | { |
| | | if (houseIndex > Kalete.Length - 1) |
| | | { |
| | | throw new ArgumentOutOfRangeException("houseIndex"); |
| | | } |
| | | info = Kalete[houseIndex]; |
| | | } |
| | | |
| | | try |
| | | { |
| | | this.HousePathInfo = HousePathInfo.FromJsonString(info); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw e; |
| | | } |
| | | |
| | | InitPathFinder(); |
| | | |
| | | } |
| | | |
| | | //凛冬 |
| | | private static readonly string[] Lingdong = new string[] { |
| | | string.Empty,//0 |
| | | //0 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //1 |
| | | "{\"Width\":30,\"Height\":30,\"RowCount\":24,\"ColCount\":45,\"Vertexs\":[],\"Edges\":[],\"Positions\":[{\"X\":1095,\"Y\":324,\"Parameter\":4},{\"X\":607,\"Y\":321,\"Parameter\":5},{\"X\":118,\"Y\":322,\"Parameter\":6},{\"X\":662,\"Y\":168,\"Parameter\":8},{\"X\":659,\"Y\":20,\"Parameter\":9}]}",//1 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //2 |
| | | "" |
| | | |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //3 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //4 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //5 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //6 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //7 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //8 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //9 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //10 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //11 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //12 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //13 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //14 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //15 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //16 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //17 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //18 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}", |
| | | //19 |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[],\"LocationPoints\":[],\"FindPathPoints\":[],\"LoopLines\":[],\"FindPathLines\":[]}" |
| | | |
| | | }; |
| | | |
| | | |
| | | //卡勒特 |
| | | private static readonly string[] Kalete = new string[] { |
| | | string.Empty ,//0 |
| | | //0: |
| | | "{\"Width\":1350,\"Height\":901,\"Obstacles\":[{\"Points\":[{\"X\":1,\"Y\":357},{\"X\":803,\"Y\":359},{\"X\":1029,\"Y\":406},{\"X\":1229,\"Y\":361},{\"X\":1346,\"Y\":357},{\"X\":1346,\"Y\":1},{\"X\":0,\"Y\":3}],\"Length\":7},{\"Points\":[{\"X\":1348,\"Y\":739},{\"X\":1254,\"Y\":735},{\"X\":1250,\"Y\":696},{\"X\":1042,\"Y\":701},{\"X\":1042,\"Y\":726},{\"X\":252,\"Y\":735},{\"X\":243,\"Y\":680},{\"X\":1,\"Y\":700},{\"X\":1,\"Y\":900},{\"X\":1347,\"Y\":901}],\"Length\":10}],\"LocationPoints\":[{\"Point\":{\"X\":100,\"Y\":411},\"Parameter\":6},{\"Point\":{\"X\":591,\"Y\":410},\"Parameter\":5},{\"Point\":{\"X\":1077,\"Y\":408},\"Parameter\":4}],\"FindPathPoints\":[{\"X\":1213,\"Y\":401},{\"X\":122,\"Y\":404}],\"LoopLines\":[{\"P1\":{\"X\":122,\"Y\":404},\"P2\":{\"X\":1213,\"Y\":401}}],\"FindPathLines\":[]}", |
| | | //1: |
| | | "{\"Width\":1349,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":124,\"Y\":324},{\"X\":760,\"Y\":310},{\"X\":956,\"Y\":414},{\"X\":1124,\"Y\":372},{\"X\":1113,\"Y\":301},{\"X\":1346,\"Y\":297},{\"X\":1345,\"Y\":3},{\"X\":0,\"Y\":2},{\"X\":0,\"Y\":375}],\"Length\":9},{\"Points\":[{\"X\":1342,\"Y\":675},{\"X\":1189,\"Y\":675},{\"X\":1191,\"Y\":713},{\"X\":949,\"Y\":712},{\"X\":867,\"Y\":772},{\"X\":840,\"Y\":897},{\"X\":1345,\"Y\":899}],\"Length\":7},{\"Points\":[{\"X\":651,\"Y\":668},{\"X\":459,\"Y\":671},{\"X\":446,\"Y\":641},{\"X\":247,\"Y\":641},{\"X\":236,\"Y\":608},{\"X\":155,\"Y\":612},{\"X\":150,\"Y\":549},{\"X\":295,\"Y\":541},{\"X\":376,\"Y\":557},{\"X\":472,\"Y\":592},{\"X\":473,\"Y\":609},{\"X\":627,\"Y\":606}],\"Length\":12},{\"Points\":[{\"X\":565,\"Y\":815},{\"X\":464,\"Y\":737},{\"X\":0,\"Y\":721},{\"X\":1,\"Y\":896},{\"X\":839,\"Y\":894},{\"X\":851,\"Y\":815}],\"Length\":6}],\"LocationPoints\":[{\"Point\":{\"X\":270,\"Y\":462},\"Parameter\":0},{\"Point\":{\"X\":732,\"Y\":461},\"Parameter\":1},{\"Point\":{\"X\":1192,\"Y\":461},\"Parameter\":2},{\"Point\":{\"X\":708,\"Y\":344},\"Parameter\":8},{\"Point\":{\"X\":706,\"Y\":197},\"Parameter\":9},{\"Point\":{\"X\":706,\"Y\":53},\"Parameter\":10}],\"FindPathPoints\":[{\"X\":1211,\"Y\":323},{\"X\":193,\"Y\":419},{\"X\":1251,\"Y\":446},{\"X\":746,\"Y\":498},{\"X\":769,\"Y\":657},{\"X\":111,\"Y\":660}],\"LoopLines\":[{\"P1\":{\"X\":193,\"Y\":419},\"P2\":{\"X\":1251,\"Y\":446}}],\"FindPathLines\":[{\"P1\":{\"X\":193,\"Y\":419},\"P2\":{\"X\":746,\"Y\":498}},{\"P1\":{\"X\":746,\"Y\":498},\"P2\":{\"X\":1251,\"Y\":446}},{\"P1\":{\"X\":746,\"Y\":498},\"P2\":{\"X\":769,\"Y\":657}},{\"P1\":{\"X\":769,\"Y\":657},\"P2\":{\"X\":1251,\"Y\":446}},{\"P1\":{\"X\":769,\"Y\":657},\"P2\":{\"X\":193,\"Y\":419}},{\"P1\":{\"X\":1251,\"Y\":446},\"P2\":{\"X\":1211,\"Y\":323}},{\"P1\":{\"X\":769,\"Y\":657},\"P2\":{\"X\":1211,\"Y\":323}},{\"P1\":{\"X\":111,\"Y\":660},\"P2\":{\"X\":193,\"Y\":419}},{\"P1\":{\"X\":111,\"Y\":660},\"P2\":{\"X\":769,\"Y\":657}}]}", |
| | | string.Empty,//2 |
| | | //3: |
| | | "{\"Width\":1348,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":0,\"Y\":313},{\"X\":927,\"Y\":295},{\"X\":963,\"Y\":334},{\"X\":1275,\"Y\":314},{\"X\":1343,\"Y\":300},{\"X\":1343,\"Y\":2},{\"X\":1,\"Y\":1}],\"Length\":7},{\"Points\":[{\"X\":878,\"Y\":366},{\"X\":750,\"Y\":369},{\"X\":733,\"Y\":354},{\"X\":740,\"Y\":325},{\"X\":876,\"Y\":324}],\"Length\":5},{\"Points\":[{\"X\":1345,\"Y\":551},{\"X\":1170,\"Y\":587},{\"X\":1173,\"Y\":643},{\"X\":1275,\"Y\":713},{\"X\":1346,\"Y\":706}],\"Length\":5},{\"Points\":[{\"X\":285,\"Y\":307},{\"X\":312,\"Y\":576},{\"X\":195,\"Y\":626},{\"X\":208,\"Y\":691},{\"X\":153,\"Y\":723},{\"X\":150,\"Y\":897},{\"X\":2,\"Y\":896},{\"X\":0,\"Y\":319}],\"Length\":8},{\"Points\":[{\"X\":156,\"Y\":752},{\"X\":369,\"Y\":714},{\"X\":793,\"Y\":734},{\"X\":932,\"Y\":822},{\"X\":1032,\"Y\":814},{\"X\":1058,\"Y\":896},{\"X\":159,\"Y\":894}],\"Length\":7},{\"Points\":[{\"X\":1037,\"Y\":824},{\"X\":1243,\"Y\":820},{\"X\":1229,\"Y\":748},{\"X\":1269,\"Y\":718},{\"X\":1344,\"Y\":709},{\"X\":1345,\"Y\":896},{\"X\":1064,\"Y\":897}],\"Length\":7}],\"LocationPoints\":[{\"Point\":{\"X\":1108,\"Y\":329},\"Parameter\":8},{\"Point\":{\"X\":1107,\"Y\":182},\"Parameter\":9},{\"Point\":{\"X\":1107,\"Y\":37},\"Parameter\":10}],\"FindPathPoints\":[{\"X\":358,\"Y\":342},{\"X\":378,\"Y\":505},{\"X\":1270,\"Y\":415},{\"X\":1038,\"Y\":650}],\"LoopLines\":[{\"P1\":{\"X\":358,\"Y\":342},\"P2\":{\"X\":1038,\"Y\":650}}],\"FindPathLines\":[{\"P1\":{\"X\":358,\"Y\":342},\"P2\":{\"X\":1270,\"Y\":415}},{\"P1\":{\"X\":1270,\"Y\":415},\"P2\":{\"X\":1038,\"Y\":650}},{\"P1\":{\"X\":1270,\"Y\":415},\"P2\":{\"X\":378,\"Y\":505}},{\"P1\":{\"X\":378,\"Y\":505},\"P2\":{\"X\":358,\"Y\":342}},{\"P1\":{\"X\":378,\"Y\":505},\"P2\":{\"X\":1038,\"Y\":650}}]}", |
| | | string.Empty,//4 |
| | | string.Empty,//5 |
| | | //6: |
| | | "{\"Width\":1350,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":325,\"Y\":425},{\"X\":437,\"Y\":447},{\"X\":567,\"Y\":437},{\"X\":565,\"Y\":395},{\"X\":631,\"Y\":398},{\"X\":675,\"Y\":410},{\"X\":809,\"Y\":405},{\"X\":810,\"Y\":375},{\"X\":933,\"Y\":329},{\"X\":1279,\"Y\":303},{\"X\":1345,\"Y\":367},{\"X\":1345,\"Y\":5},{\"X\":1,\"Y\":6}],\"Length\":13},{\"Points\":[{\"X\":1347,\"Y\":481},{\"X\":1246,\"Y\":501},{\"X\":1235,\"Y\":551},{\"X\":1188,\"Y\":617},{\"X\":1192,\"Y\":669},{\"X\":1348,\"Y\":673}],\"Length\":6},{\"Points\":[{\"X\":1349,\"Y\":701},{\"X\":791,\"Y\":719},{\"X\":803,\"Y\":659},{\"X\":396,\"Y\":665},{\"X\":361,\"Y\":723},{\"X\":2,\"Y\":711},{\"X\":0,\"Y\":896},{\"X\":1345,\"Y\":898}],\"Length\":8}],\"LocationPoints\":[{\"Point\":{\"X\":1080,\"Y\":425},\"Parameter\":4},{\"Point\":{\"X\":592,\"Y\":427},\"Parameter\":5},{\"Point\":{\"X\":103,\"Y\":427},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":174,\"Y\":537},{\"X\":1197,\"Y\":430},{\"X\":602,\"Y\":502}],\"LoopLines\":[{\"P1\":{\"X\":174,\"Y\":537},\"P2\":{\"X\":1197,\"Y\":430}}],\"FindPathLines\":[{\"P1\":{\"X\":174,\"Y\":537},\"P2\":{\"X\":602,\"Y\":502}},{\"P1\":{\"X\":602,\"Y\":502},\"P2\":{\"X\":1197,\"Y\":430}}]}", |
| | | //7: |
| | | "{\"Width\":1350,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":31,\"Y\":409},{\"X\":127,\"Y\":312},{\"X\":505,\"Y\":351},{\"X\":570,\"Y\":394},{\"X\":733,\"Y\":418},{\"X\":888,\"Y\":410},{\"X\":896,\"Y\":334},{\"X\":1066,\"Y\":328},{\"X\":1100,\"Y\":401},{\"X\":1315,\"Y\":425},{\"X\":1349,\"Y\":427},{\"X\":1343,\"Y\":1},{\"X\":4,\"Y\":4},{\"X\":1,\"Y\":341}],\"Length\":14},{\"Points\":[{\"X\":467,\"Y\":896},{\"X\":472,\"Y\":733},{\"X\":325,\"Y\":676},{\"X\":178,\"Y\":636},{\"X\":0,\"Y\":625},{\"X\":2,\"Y\":900}],\"Length\":6}],\"LocationPoints\":[{\"Point\":{\"X\":270,\"Y\":462},\"Parameter\":0},{\"Point\":{\"X\":730,\"Y\":463},\"Parameter\":1},{\"Point\":{\"X\":1191,\"Y\":463},\"Parameter\":2},{\"Point\":{\"X\":1078,\"Y\":499},\"Parameter\":4},{\"Point\":{\"X\":589,\"Y\":497},\"Parameter\":5},{\"Point\":{\"X\":100,\"Y\":498},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":146,\"Y\":440},{\"X\":1226,\"Y\":720}],\"LoopLines\":[{\"P1\":{\"X\":146,\"Y\":440},\"P2\":{\"X\":1226,\"Y\":720}}],\"FindPathLines\":[]}", |
| | | //8: |
| | | "{\"Width\":1686,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":2,\"Y\":420},{\"X\":130,\"Y\":439},{\"X\":311,\"Y\":462},{\"X\":313,\"Y\":400},{\"X\":221,\"Y\":319},{\"X\":453,\"Y\":288},{\"X\":632,\"Y\":5},{\"X\":4,\"Y\":2}],\"Length\":8},{\"Points\":[{\"X\":574,\"Y\":104},{\"X\":743,\"Y\":319},{\"X\":961,\"Y\":306},{\"X\":1014,\"Y\":343},{\"X\":1099,\"Y\":326},{\"X\":1165,\"Y\":369},{\"X\":1534,\"Y\":365},{\"X\":1684,\"Y\":309},{\"X\":1680,\"Y\":4},{\"X\":633,\"Y\":5}],\"Length\":10},{\"Points\":[{\"X\":1682,\"Y\":470},{\"X\":1540,\"Y\":514},{\"X\":1442,\"Y\":590},{\"X\":1173,\"Y\":641},{\"X\":858,\"Y\":670},{\"X\":814,\"Y\":708},{\"X\":1681,\"Y\":715}],\"Length\":7}],\"LocationPoints\":[{\"Point\":{\"X\":277,\"Y\":501},\"Parameter\":0},{\"Point\":{\"X\":735,\"Y\":502},\"Parameter\":1},{\"Point\":{\"X\":1196,\"Y\":502},\"Parameter\":2},{\"Point\":{\"X\":1418,\"Y\":390},\"Parameter\":4},{\"Point\":{\"X\":930,\"Y\":387},\"Parameter\":5},{\"Point\":{\"X\":441,\"Y\":388},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":186,\"Y\":483},{\"X\":1565,\"Y\":393},{\"X\":549,\"Y\":448}],\"LoopLines\":[{\"P1\":{\"X\":186,\"Y\":483},\"P2\":{\"X\":1565,\"Y\":393}}],\"FindPathLines\":[{\"P1\":{\"X\":186,\"Y\":483},\"P2\":{\"X\":549,\"Y\":448}},{\"P1\":{\"X\":549,\"Y\":448},\"P2\":{\"X\":1565,\"Y\":393}}]}", |
| | | //9: |
| | | "{\"Width\":1688,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":3,\"Y\":333},{\"X\":390,\"Y\":305},{\"X\":600,\"Y\":389},{\"X\":746,\"Y\":389},{\"X\":766,\"Y\":327},{\"X\":890,\"Y\":334},{\"X\":914,\"Y\":247},{\"X\":1092,\"Y\":225},{\"X\":1305,\"Y\":396},{\"X\":1489,\"Y\":346},{\"X\":1684,\"Y\":411},{\"X\":1683,\"Y\":3},{\"X\":3,\"Y\":3}],\"Length\":13},{\"Points\":[{\"X\":389,\"Y\":671},{\"X\":398,\"Y\":614},{\"X\":868,\"Y\":605},{\"X\":1037,\"Y\":631},{\"X\":1125,\"Y\":589},{\"X\":1536,\"Y\":632},{\"X\":1678,\"Y\":682},{\"X\":1682,\"Y\":715},{\"X\":378,\"Y\":715}],\"Length\":9}],\"LocationPoints\":[{\"Point\":{\"X\":274,\"Y\":500},\"Parameter\":0},{\"Point\":{\"X\":738,\"Y\":502},\"Parameter\":1},{\"Point\":{\"X\":1200,\"Y\":501},\"Parameter\":2},{\"Point\":{\"X\":1658,\"Y\":503},\"Parameter\":3}],\"FindPathPoints\":[{\"X\":216,\"Y\":456},{\"X\":1545,\"Y\":466},{\"X\":985,\"Y\":515}],\"LoopLines\":[{\"P1\":{\"X\":216,\"Y\":456},\"P2\":{\"X\":1545,\"Y\":466}}],\"FindPathLines\":[{\"P1\":{\"X\":216,\"Y\":456},\"P2\":{\"X\":985,\"Y\":515}},{\"P1\":{\"X\":985,\"Y\":515},\"P2\":{\"X\":1545,\"Y\":466}}]}", |
| | | string.Empty,//10 |
| | | //11: |
| | | "{\"Width\":1686,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":1678,\"Y\":410},{\"X\":1576,\"Y\":341},{\"X\":1258,\"Y\":344},{\"X\":1241,\"Y\":379},{\"X\":1153,\"Y\":380},{\"X\":849,\"Y\":377},{\"X\":765,\"Y\":353},{\"X\":598,\"Y\":352},{\"X\":498,\"Y\":387},{\"X\":0,\"Y\":360},{\"X\":1,\"Y\":1},{\"X\":1681,\"Y\":2}],\"Length\":12},{\"Points\":[{\"X\":1566,\"Y\":714},{\"X\":1502,\"Y\":662},{\"X\":875,\"Y\":654},{\"X\":780,\"Y\":660},{\"X\":550,\"Y\":636},{\"X\":365,\"Y\":614},{\"X\":183,\"Y\":626},{\"X\":72,\"Y\":636},{\"X\":10,\"Y\":655},{\"X\":0,\"Y\":715}],\"Length\":10}],\"LocationPoints\":[{\"Point\":{\"X\":929,\"Y\":450},\"Parameter\":5},{\"Point\":{\"X\":440,\"Y\":452},\"Parameter\":6},{\"Point\":{\"X\":1416,\"Y\":451},\"Parameter\":4}],\"FindPathPoints\":[{\"X\":71,\"Y\":469},{\"X\":1529,\"Y\":462},{\"X\":826,\"Y\":576}],\"LoopLines\":[{\"P1\":{\"X\":71,\"Y\":469},\"P2\":{\"X\":1529,\"Y\":462}}],\"FindPathLines\":[{\"P1\":{\"X\":71,\"Y\":469},\"P2\":{\"X\":826,\"Y\":576}},{\"P1\":{\"X\":826,\"Y\":576},\"P2\":{\"X\":1529,\"Y\":462}}]}", |
| | | //12: |
| | | "{\"Width\":2024,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":795,\"Y\":351},{\"X\":1897,\"Y\":323},{\"X\":2019,\"Y\":271},{\"X\":2019,\"Y\":4},{\"X\":1,\"Y\":2},{\"X\":3,\"Y\":347},{\"X\":111,\"Y\":400},{\"X\":200,\"Y\":377},{\"X\":294,\"Y\":344},{\"X\":560,\"Y\":351},{\"X\":623,\"Y\":381}],\"Length\":11},{\"Points\":[{\"X\":2020,\"Y\":614},{\"X\":1464,\"Y\":615},{\"X\":1137,\"Y\":589},{\"X\":895,\"Y\":606},{\"X\":855,\"Y\":715},{\"X\":2020,\"Y\":716}],\"Length\":6},{\"Points\":[{\"X\":525,\"Y\":715},{\"X\":451,\"Y\":589},{\"X\":156,\"Y\":603},{\"X\":2,\"Y\":495},{\"X\":2,\"Y\":716}],\"Length\":5}],\"LocationPoints\":[{\"Point\":{\"X\":270,\"Y\":461},\"Parameter\":0},{\"Point\":{\"X\":731,\"Y\":461},\"Parameter\":1},{\"Point\":{\"X\":1192,\"Y\":462},\"Parameter\":2},{\"Point\":{\"X\":1650,\"Y\":463},\"Parameter\":3},{\"Point\":{\"X\":1278,\"Y\":347},\"Parameter\":5},{\"Point\":{\"X\":788,\"Y\":347},\"Parameter\":6},{\"Point\":{\"X\":301,\"Y\":346},\"Parameter\":7},{\"Point\":{\"X\":628,\"Y\":175},\"Parameter\":8},{\"Point\":{\"X\":627,\"Y\":28},\"Parameter\":9}],\"FindPathPoints\":[{\"X\":201,\"Y\":457},{\"X\":1894,\"Y\":423},{\"X\":699,\"Y\":513}],\"LoopLines\":[{\"P1\":{\"X\":201,\"Y\":457},\"P2\":{\"X\":1894,\"Y\":423}}],\"FindPathLines\":[{\"P1\":{\"X\":201,\"Y\":457},\"P2\":{\"X\":699,\"Y\":513}},{\"P1\":{\"X\":699,\"Y\":513},\"P2\":{\"X\":1894,\"Y\":423}}]}", |
| | | //13: |
| | | "{\"Width\":2024,\"Height\":900,\"Obstacles\":[{\"Points\":[{\"X\":1607,\"Y\":189},{\"X\":1761,\"Y\":360},{\"X\":2022,\"Y\":405},{\"X\":2022,\"Y\":1},{\"X\":1565,\"Y\":1}],\"Length\":5},{\"Points\":[{\"X\":1350,\"Y\":400},{\"X\":1605,\"Y\":186},{\"X\":1562,\"Y\":1},{\"X\":121,\"Y\":1},{\"X\":335,\"Y\":410},{\"X\":385,\"Y\":402}],\"Length\":6},{\"Points\":[{\"X\":2017,\"Y\":719},{\"X\":1228,\"Y\":729},{\"X\":1137,\"Y\":666},{\"X\":667,\"Y\":689},{\"X\":417,\"Y\":671},{\"X\":123,\"Y\":649},{\"X\":121,\"Y\":891},{\"X\":2020,\"Y\":896}],\"Length\":8},{\"Points\":[{\"X\":294,\"Y\":564},{\"X\":121,\"Y\":566},{\"X\":122,\"Y\":19},{\"X\":322,\"Y\":394},{\"X\":233,\"Y\":457}],\"Length\":5},{\"Points\":[{\"X\":1,\"Y\":2},{\"X\":127,\"Y\":3},{\"X\":128,\"Y\":896},{\"X\":0,\"Y\":894}],\"Length\":4}],\"LocationPoints\":[{\"Point\":{\"X\":537,\"Y\":496},\"Parameter\":0},{\"Point\":{\"X\":997,\"Y\":497},\"Parameter\":1},{\"Point\":{\"X\":1458,\"Y\":497},\"Parameter\":2},{\"Point\":{\"X\":1918,\"Y\":496},\"Parameter\":3},{\"Point\":{\"X\":777,\"Y\":484},\"Parameter\":6},{\"Point\":{\"X\":1266,\"Y\":484},\"Parameter\":5},{\"Point\":{\"X\":1753,\"Y\":485},\"Parameter\":4}],\"FindPathPoints\":[{\"X\":425,\"Y\":495},{\"X\":1885,\"Y\":496},{\"X\":1294,\"Y\":541}],\"LoopLines\":[{\"P1\":{\"X\":425,\"Y\":495},\"P2\":{\"X\":1885,\"Y\":496}}],\"FindPathLines\":[{\"P1\":{\"X\":425,\"Y\":495},\"P2\":{\"X\":1294,\"Y\":541}},{\"P1\":{\"X\":1294,\"Y\":541},\"P2\":{\"X\":1885,\"Y\":496}}]}", |
| | | //14: |
| | | "{\"Width\":1687,\"Height\":901,\"Obstacles\":[{\"Points\":[{\"X\":98,\"Y\":310},{\"X\":408,\"Y\":314},{\"X\":418,\"Y\":425},{\"X\":530,\"Y\":416},{\"X\":593,\"Y\":451},{\"X\":721,\"Y\":452},{\"X\":762,\"Y\":449},{\"X\":783,\"Y\":337},{\"X\":840,\"Y\":302},{\"X\":1207,\"Y\":300},{\"X\":1239,\"Y\":321},{\"X\":1418,\"Y\":320},{\"X\":1584,\"Y\":378},{\"X\":1679,\"Y\":377},{\"X\":1681,\"Y\":4},{\"X\":4,\"Y\":4},{\"X\":0,\"Y\":436}],\"Length\":17},{\"Points\":[{\"X\":1681,\"Y\":717},{\"X\":1319,\"Y\":706},{\"X\":1165,\"Y\":653},{\"X\":1053,\"Y\":654},{\"X\":835,\"Y\":609},{\"X\":732,\"Y\":624},{\"X\":680,\"Y\":667},{\"X\":0,\"Y\":650},{\"X\":0,\"Y\":898},{\"X\":1682,\"Y\":898}],\"Length\":10}],\"LocationPoints\":[{\"Point\":{\"X\":278,\"Y\":481},\"Parameter\":0},{\"Point\":{\"X\":739,\"Y\":481},\"Parameter\":1},{\"Point\":{\"X\":1200,\"Y\":479},\"Parameter\":2},{\"Point\":{\"X\":1656,\"Y\":480},\"Parameter\":3}],\"FindPathPoints\":[{\"X\":140,\"Y\":474},{\"X\":1453,\"Y\":466},{\"X\":763,\"Y\":520},{\"X\":373,\"Y\":565}],\"LoopLines\":[{\"P1\":{\"X\":140,\"Y\":474},\"P2\":{\"X\":1453,\"Y\":466}}],\"FindPathLines\":[{\"P1\":{\"X\":140,\"Y\":474},\"P2\":{\"X\":373,\"Y\":565}},{\"P1\":{\"X\":140,\"Y\":474},\"P2\":{\"X\":763,\"Y\":520}},{\"P1\":{\"X\":373,\"Y\":565},\"P2\":{\"X\":763,\"Y\":520}},{\"P1\":{\"X\":763,\"Y\":520},\"P2\":{\"X\":1453,\"Y\":466}},{\"P1\":{\"X\":373,\"Y\":565},\"P2\":{\"X\":1453,\"Y\":466}}]}", |
| | | string.Empty,//15 |
| | | //16: |
| | | "{\"Width\":1687,\"Height\":901,\"Obstacles\":[{\"Points\":[{\"X\":3,\"Y\":385},{\"X\":257,\"Y\":388},{\"X\":655,\"Y\":320},{\"X\":711,\"Y\":264},{\"X\":1682,\"Y\":279},{\"X\":1682,\"Y\":1},{\"X\":0,\"Y\":4}],\"Length\":7},{\"Points\":[{\"X\":5,\"Y\":713},{\"X\":265,\"Y\":754},{\"X\":432,\"Y\":862},{\"X\":405,\"Y\":900},{\"X\":1,\"Y\":896}],\"Length\":5},{\"Points\":[{\"X\":720,\"Y\":883},{\"X\":825,\"Y\":776},{\"X\":1034,\"Y\":851},{\"X\":985,\"Y\":900},{\"X\":712,\"Y\":900}],\"Length\":5},{\"Points\":[{\"X\":1173,\"Y\":871},{\"X\":1569,\"Y\":644},{\"X\":1674,\"Y\":661},{\"X\":1684,\"Y\":772},{\"X\":1679,\"Y\":887},{\"X\":1187,\"Y\":893},{\"X\":1200,\"Y\":852}],\"Length\":7}],\"LocationPoints\":[{\"Point\":{\"X\":1391,\"Y\":410},\"Parameter\":4},{\"Point\":{\"X\":905,\"Y\":409},\"Parameter\":5},{\"Point\":{\"X\":416,\"Y\":410},\"Parameter\":6}],\"FindPathPoints\":[{\"X\":633,\"Y\":693},{\"X\":1494,\"Y\":434},{\"X\":139,\"Y\":505},{\"X\":834,\"Y\":367}],\"LoopLines\":[{\"P1\":{\"X\":139,\"Y\":505},\"P2\":{\"X\":1494,\"Y\":434}}],\"FindPathLines\":[{\"P1\":{\"X\":139,\"Y\":505},\"P2\":{\"X\":834,\"Y\":367}},{\"P1\":{\"X\":834,\"Y\":367},\"P2\":{\"X\":1494,\"Y\":434}},{\"P1\":{\"X\":633,\"Y\":693},\"P2\":{\"X\":1494,\"Y\":434}},{\"P1\":{\"X\":633,\"Y\":693},\"P2\":{\"X\":834,\"Y\":367}},{\"P1\":{\"X\":633,\"Y\":693},\"P2\":{\"X\":139,\"Y\":505}}]}", |
| | | //17: |
| | | "{\"Width\":1687,\"Height\":720,\"Obstacles\":[{\"Points\":[{\"X\":1681,\"Y\":368},{\"X\":1591,\"Y\":363},{\"X\":1487,\"Y\":252},{\"X\":1475,\"Y\":4},{\"X\":1683,\"Y\":3}],\"Length\":5},{\"Points\":[{\"X\":1348,\"Y\":358},{\"X\":544,\"Y\":345},{\"X\":534,\"Y\":453},{\"X\":115,\"Y\":450},{\"X\":0,\"Y\":390},{\"X\":0,\"Y\":3},{\"X\":1480,\"Y\":3},{\"X\":1487,\"Y\":245}],\"Length\":8},{\"Points\":[{\"X\":108,\"Y\":685},{\"X\":76,\"Y\":720},{\"X\":1682,\"Y\":718},{\"X\":1684,\"Y\":683}],\"Length\":4}],\"LocationPoints\":[{\"Point\":{\"X\":276,\"Y\":499},\"Parameter\":0},{\"Point\":{\"X\":736,\"Y\":502},\"Parameter\":1},{\"Point\":{\"X\":1198,\"Y\":500},\"Parameter\":2},{\"Point\":{\"X\":1655,\"Y\":502},\"Parameter\":3}],\"FindPathPoints\":[{\"X\":196,\"Y\":514},{\"X\":1622,\"Y\":491},{\"X\":605,\"Y\":518}],\"LoopLines\":[{\"P1\":{\"X\":196,\"Y\":514},\"P2\":{\"X\":1622,\"Y\":491}}],\"FindPathLines\":[{\"P1\":{\"X\":196,\"Y\":514},\"P2\":{\"X\":605,\"Y\":518}},{\"P1\":{\"X\":605,\"Y\":518},\"P2\":{\"X\":1622,\"Y\":491}}]}", |
| | | }; |
| | | |
| | | /// <summary> |
| | | /// 房间信息 |
| | | /// </summary> |
| | | public HousePathInfo HouseInfo { get; private set; } |
| | | public HousePathInfo HousePathInfo { get; private set; } |
| | | |
| | | /// <summary> |
| | | /// 路径查找器 |
| | | /// </summary> |
| | | public Dijkstra<ZTPoint> PathFinder { get; private set; } |
| | | |
| | | /// <summary> |
| | | /// 定位字典 |
| | | /// </summary> |
| | | private Dictionary<Int32, ZTPoint> LocationDic = new Dictionary<int, ZTPoint>(); |
| | | |
| | | /// <summary> |
| | | /// 屏幕坐标转地图坐标 |
| | | /// </summary> |
| | | /// <param name="screenCoordinate"></param> |
| | | /// <param name="locationParameter"></param> |
| | | /// <param name="locationCoordinate"></param> |
| | | /// <returns></returns> |
| | | public ZTPoint ScreenToMapCoordinate(ZTPoint screenCoordinate,Int32 locationParameter,ZTPoint locationScreenCoordinate) |
| | | { |
| | | if (!LocationDic.ContainsKey(locationParameter)) |
| | | { |
| | | throw new ArgumentOutOfRangeException("不存在的定位点,parameter:"+locationParameter.ToString()); |
| | | } |
| | | |
| | | //目标屏幕坐标+(定位点地图坐标-定位点屏幕坐标) |
| | | return screenCoordinate.Add(LocationDic[locationParameter].Sub(locationScreenCoordinate)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 地图坐标转屏幕坐标 |
| | | /// </summary> |
| | | /// <param name="mapCoordinate"></param> |
| | | /// <param name="locationParameter"></param> |
| | | /// <param name="locationCoordinate"></param> |
| | | /// <returns></returns> |
| | | public ZTPoint MapToScreenCoordinate(ZTPoint mapCoordinate, Int32 locationParameter, ZTPoint locationScreenCoordinate) |
| | | { |
| | | if (!LocationDic.ContainsKey(locationParameter)) |
| | | { |
| | | throw new ArgumentOutOfRangeException("不存在的定位点,parameter:" + locationParameter.ToString()); |
| | | } |
| | | |
| | | //目标地图坐标-(定位点地图坐标-定位点屏幕坐标) |
| | | return mapCoordinate.Sub(LocationDic[locationParameter].Sub(locationScreenCoordinate)); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 寻找巡逻路线 |
| | | /// </summary> |
| | |
| | | private bool Iscross(ZTPoint start, ZTPoint end) |
| | | { |
| | | |
| | | for (int i = 0; i < this.HouseInfo.Obstacles.Count; i++) |
| | | for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++) |
| | | { |
| | | Intersection interSection = GeometryHelper.IntersectionOf(new ZTLinePoint(start, end), this.HouseInfo.Obstacles[i]); |
| | | Intersection interSection = GeometryHelper.IntersectionOf(new ZTLinePoint(start, end), this.HousePathInfo.Obstacles[i]); |
| | | if (interSection != Intersection.None) |
| | | { |
| | | return false; |
| | |
| | | { |
| | | ZTPoint source = new ZTPoint(point.X, point.Y); |
| | | ZTPolygon obstacle = ZTPolygon.Empty; |
| | | for (int i = 0; i < this.HouseInfo.Obstacles.Count; i++) |
| | | for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++) |
| | | { |
| | | ZTPolygon temp = this.HouseInfo.Obstacles[i]; |
| | | ZTPolygon temp = this.HousePathInfo.Obstacles[i]; |
| | | if (GeometryHelper.IntersectionOf(point, temp) != Intersection.None) |
| | | { |
| | | obstacle = this.HouseInfo.Obstacles[i]; |
| | | obstacle = this.HousePathInfo.Obstacles[i]; |
| | | break; |
| | | } |
| | | } |
| | |
| | | |
| | | //查找最近离开障碍物的点 |
| | | ZTPoint testPoint = new ZTPoint(point.X, point.Y); |
| | | Int32 maxDistance = Math.Max(Math.Max(point.X, this.HouseInfo.Width - point.X), Math.Max(point.Y, this.HouseInfo.Height - point.Y)); |
| | | Int32 maxDistance = Math.Max(Math.Max(point.X, this.HousePathInfo.Width - point.X), Math.Max(point.Y, this.HousePathInfo.Height - point.Y)); |
| | | for (int i = (Int32)distance; i < maxDistance; i++) |
| | | { |
| | | //下 |
| | | if (point.Y + i <= this.HouseInfo.Height) |
| | | if (point.Y + i <= this.HousePathInfo.Height) |
| | | { |
| | | testPoint = new ZTPoint(point.X, point.Y + i); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | |
| | | |
| | | |
| | | //右 |
| | | if (point.X <= this.HouseInfo.Width) |
| | | if (point.X <= this.HousePathInfo.Width) |
| | | { |
| | | testPoint = new ZTPoint(point.X + i, point.Y); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | |
| | | |
| | | //添加寻路路径 |
| | | ZTLinePoint line; |
| | | for (int i = 0; i < this.HouseInfo.FindPathLines.Count; i++) |
| | | for (int i = 0; i < this.HousePathInfo.FindPathLines.Count; i++) |
| | | { |
| | | line = this.HouseInfo.FindPathLines[i]; |
| | | line = this.HousePathInfo.FindPathLines[i]; |
| | | this.PathFinder.AddVertex(line.P1, line.P2, line.GetDistance()); |
| | | } |
| | | |
| | | //添加巡逻路径 |
| | | for (int i = 0; i < this.HouseInfo.LoopLines.Count; i++) |
| | | for (int i = 0; i < this.HousePathInfo.LoopLines.Count; i++) |
| | | { |
| | | line = this.HouseInfo.LoopLines[i]; |
| | | line = this.HousePathInfo.LoopLines[i]; |
| | | this.PathFinder.AddVertex(line.P1, line.P2, line.GetDistance()); |
| | | } |
| | | |
| | | //定位点添加到字典 |
| | | for (int i = 0; i < this.HousePathInfo.LocationPoints.Count; i++) |
| | | { |
| | | ParametersPoint pp = this.HousePathInfo.LocationPoints[i]; |
| | | if (!this.LocationDic.ContainsKey(pp.Parameter)) |
| | | { |
| | | this.LocationDic.Add(pp.Parameter, pp.Point); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | Int32 distance = 0; |
| | | ZTPoint point; |
| | | for (int i = 0; i < this.HouseInfo.FindPathPoints.Count; i++) |
| | | for (int i = 0; i < this.HousePathInfo.FindPathPoints.Count; i++) |
| | | { |
| | | point = this.HouseInfo.FindPathPoints[i]; |
| | | point = this.HousePathInfo.FindPathPoints[i]; |
| | | if (Iscross(start, point)) |
| | | { |
| | | distance = (Int32)GeometryHelper.GetPointDistance(start, point); |
| | |
| | | { |
| | | public class Dijkstra<T> where T : IEquatable<T> |
| | | { |
| | | private Dictionary<T, Dictionary<T, Int32>> vertices = new Dictionary<T, Dictionary<T, Int32>>(); |
| | | private Dictionary<T, Dictionary<T, Int32>> edges = new Dictionary<T, Dictionary<T, Int32>>(); |
| | | |
| | | /// <summary> |
| | | /// 添加顶点 |
| | | /// </summary> |
| | | /// <param name="name">顶点名称</param> |
| | | /// <param name="edges">顶点所有的边</param> |
| | | public void AddVertex(T name, Dictionary<T, Int32> edges) |
| | | /// <param name="vertice">顶点名称</param> |
| | | /// <param name="targetVertice">顶点所有的边</param> |
| | | public void AddEdge(T vertice, Dictionary<T, Int32> targetVertice) |
| | | { |
| | | foreach (var item in edges) |
| | | foreach (var item in targetVertice) |
| | | { |
| | | AddVertex(name, item.Key, item.Value); |
| | | AddEdge(vertice, item.Key, item.Value); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加顶点 |
| | | /// </summary> |
| | | /// <param name="name">顶点名称</param> |
| | | /// <param name="target">可连接顶点</param> |
| | | /// <param name="vertice">顶点名称</param> |
| | | /// <param name="targetVertice">可连接顶点</param> |
| | | /// <param name="weight">权重</param> |
| | | public void AddVertex(T name, T target, Int32 weight) |
| | | public void AddEdge(T vertice, T targetVertice, Int32 weight) |
| | | { |
| | | if (!this.vertices.ContainsKey(name)) |
| | | if (!this.edges.ContainsKey(vertice)) |
| | | { |
| | | this.vertices.Add(name, new Dictionary<T, Int32>()); |
| | | this.edges.Add(vertice, new Dictionary<T, Int32>()); |
| | | } |
| | | |
| | | if (!this.vertices[name].ContainsKey(target)) |
| | | if (!this.edges[vertice].ContainsKey(targetVertice)) |
| | | { |
| | | this.vertices[name].Add(target, weight); |
| | | this.edges[vertice].Add(targetVertice, weight); |
| | | } |
| | | |
| | | |
| | | if (!this.vertices.ContainsKey(target)) |
| | | if (!this.edges.ContainsKey(targetVertice)) |
| | | { |
| | | this.vertices.Add(target, new Dictionary<T, Int32>()); |
| | | this.edges.Add(targetVertice, new Dictionary<T, Int32>()); |
| | | } |
| | | |
| | | |
| | | if (!this.vertices[target].ContainsKey(name)) |
| | | if (!this.edges[targetVertice].ContainsKey(vertice)) |
| | | { |
| | | this.vertices[target].Add(name, weight); |
| | | this.edges[targetVertice].Add(vertice, weight); |
| | | } |
| | | |
| | | } |
| | |
| | | /// 移除顶点 |
| | | /// </summary> |
| | | /// <param name="name"></param> |
| | | public void RemoveVertex(T name) |
| | | public void RemoveEdge(T name) |
| | | { |
| | | if (this.vertices.ContainsKey(name)) |
| | | if (this.edges.ContainsKey(name)) |
| | | { |
| | | return; |
| | | } |
| | | this.vertices.Remove(name); |
| | | foreach (var item in this.vertices) |
| | | this.edges.Remove(name); |
| | | foreach (var item in this.edges) |
| | | { |
| | | if (item.Value.ContainsKey(name)) |
| | | { |
| | |
| | | |
| | | List<T> path = null; |
| | | |
| | | foreach (var vertex in vertices) |
| | | foreach (var vertex in edges) |
| | | { |
| | | if (vertex.Key.Equals(start)) |
| | | { |
| | |
| | | break; |
| | | } |
| | | |
| | | foreach (var neighbor in vertices[smallest]) |
| | | foreach (var neighbor in edges[smallest]) |
| | | { |
| | | var alt = distances[smallest] + neighbor.Value; |
| | | if (alt < distances[neighbor.Key]) |
| | |
| | | <Compile Include="CV\CVHelper.cs" /> |
| | | <Compile Include="CV\ChannelCVHelper.cs" /> |
| | | <Compile Include="CV\GroupCVHelper.cs" /> |
| | | <Compile Include="CV\KaleteCVHelper.cs" /> |
| | | <Compile Include="CV\SkillCVHelper.cs" /> |
| | | <Compile Include="CV\DnfCVHelper.cs" /> |
| | | <Compile Include="CV\LindongCVHelper.cs" /> |
| | | <Compile Include="CV\WeGameCVHelper.cs" /> |
| | | <Compile Include="Dnf\MoveIntent.cs" /> |
| | | <Compile Include="Dnf\MoveMethod.cs" /> |
| | | <Compile Include="ImageHelper.cs" /> |
| | | <Compile Include="InputControl\HardwareInputControl.cs" /> |
| | | <Compile Include="InputControl\HIDCode.cs" /> |
| | | <Compile Include="InputControl\IInputControl.cs" /> |
| | | <Compile Include="InputControl\NativeInputControl.cs" /> |
| | | <Compile Include="InputControl\SerialPortConnect.cs" /> |
| | | <Compile Include="Maps\HouseInfo.cs" /> |
| | | <Compile Include="Maps\MapType.cs" /> |
| | | <Compile Include="Maps\MovePriority.cs" /> |
| | | <Compile Include="MouseHook.cs" /> |
| | | <Compile Include="PathFinding\AStarFinding\PathGrid.cs" /> |
| | | <Compile Include="PathFinding\AStarFinding\PathNode.cs" /> |
| | | <Compile Include="PathFinding\AStarFinding\Point2.cs" /> |
| | | <Compile Include="PathFinding\Dijkstra.cs" /> |
| | | <Compile Include="PathFinding\DNFPathFinding.cs" /> |
| | | <Compile Include="Properties\AssemblyInfo.cs" /> |
| | | <Compile Include="Skills\SkillInfo.cs" /> |
| | | <Compile Include="Skills\SkillQueue.cs" /> |
| | | <Compile Include="Dnf\SpeedProvider.cs" /> |
| | | <Compile Include="Structs\ColorArray.cs" /> |
| | | <Compile Include="Structs\ColorArrayItem.cs" /> |
| | | <Compile Include="Structs\Direction.cs" /> |
| | | <Compile Include="Structs\HousePathInfo.cs" /> |
| | | <Compile Include="Maps\HousePathInfo.cs" /> |
| | | <Compile Include="Structs\HousePathInfoObj.cs" /> |
| | | <Compile Include="Structs\ParametersPoint.cs" /> |
| | | <Compile Include="Structs\ParametersPointObj.cs" /> |
| | | <Compile Include="Structs\ZTLinePoint.cs" /> |
| | | <Compile Include="Structs\MoveQueueItem.cs" /> |
| | | <Compile Include="Structs\Orientation.cs" /> |
| | | <Compile Include="Structs\FindPathInfo.cs" /> |
| | | <Compile Include="Structs\ZTLinePointObj.cs" /> |
| | | <Compile Include="Structs\ZTPointObj.cs" /> |
| | | <Compile Include="Structs\ZTPolygon.cs" /> |
| | |
| | | <Compile Include="Structs\ZTHsvFloatColorArrayItem.cs" /> |
| | | <Compile Include="Structs\ZTLine.cs" /> |
| | | <Compile Include="Structs\ZTPoint.cs" /> |
| | | <Compile Include="Structs\ZTTargetPolygonObj.cs" /> |
| | | <Compile Include="Structs\ZTPolygonObj.cs" /> |
| | | <Compile Include="Structs\ZTRectangle.cs" /> |
| | | <Compile Include="Structs\ZTSize.cs" /> |
| | | <Compile Include="Structs\ZTSizeDouble.cs" /> |
| | | <Compile Include="Structs\ZTTargetPolygon.cs" /> |
| | | <Compile Include="Utilitys\ColorUtils.cs" /> |
| | | <Compile Include="Utilitys\GeometryHelper.cs" /> |
| | | <Compile Include="Utilitys\ProcessUtils.cs" /> |
| | | <Compile Include="Utilitys\RandomUtils.cs" /> |
| | | <Compile Include="Utilitys\SystemHotKey.cs" /> |
| | | <Compile Include="Utilitys\WindowUtils.cs" /> |
| | | <Compile Include="Utils.cs" /> |
| | | <Compile Include="ZTResult.cs" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Content Include="License-LGPL.txt" /> |
| New file |
| | |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | using RichCreator.Utility.Maps; |
| | | |
| | | namespace RichCreator.Utility.Skills |
| | | { |
| | | /// <summary> |
| | | /// 技能信息 |
| | | /// </summary> |
| | | public class SkillInfo |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 技能列表 |
| | | /// </summary> |
| | | private static Dictionary<HIDCode, SkillInfo> Skills = new Dictionary<HIDCode, SkillInfo>() { |
| | | { HIDCode.Q,new SkillInfo (){ Key=HIDCode.Q,Range=new ZTSize (700,200),WaitTime=9, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=2000,SkillName="朔风牵引"} }, |
| | | { HIDCode.W,new SkillInfo (){ Key=HIDCode.W,Range=new ZTSize (620,240),WaitTime=45, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Center,ReleaseTime=2000,SkillName="风卷残云"} }, |
| | | { HIDCode.E,new SkillInfo (){ Key=HIDCode.E,Range=new ZTSize (1280,200),WaitTime=12.6f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=2000,SkillName="双翼风刃"} }, |
| | | { HIDCode.R,new SkillInfo (){ Key=HIDCode.R,Range=new ZTSize (400,200),WaitTime=14.4f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=600,SkillName="风暴之眼"} }, |
| | | { HIDCode.T,new SkillInfo (){ Key=HIDCode.T,Range=new ZTSize (120,300),WaitTime=40.5f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=2000,SkillName="九霄风雷"} }, |
| | | { HIDCode.Y,new SkillInfo (){ Key=HIDCode.Y,Range=new ZTSize (1280,720),WaitTime=145, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Center,ReleaseTime=2000,SkillName="万象风龙阵"} }, |
| | | |
| | | |
| | | { HIDCode.A,new SkillInfo (){ Key=HIDCode.A,Range=new ZTSize (240,148),WaitTime=7.7f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Nearly,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=600,SkillName="风鸣冲击"} }, |
| | | { HIDCode.S,new SkillInfo (){ Key=HIDCode.S,Range=new ZTSize (180,430),WaitTime=22.5f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=2000,SkillName="真空旋风破"} }, |
| | | { HIDCode.D,new SkillInfo (){ Key=HIDCode.D,Range=new ZTSize (1280,240),WaitTime=6.3f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=500,SkillName="游离之风"} }, |
| | | { HIDCode.F,new SkillInfo (){ Key=HIDCode.F,Range=new ZTSize (370,224),WaitTime=40.5f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=2000,SkillName="风暴之拳"} }, |
| | | { HIDCode.G,new SkillInfo (){ Key=HIDCode.G,Range=new ZTSize (730,218),WaitTime=36, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=2000,SkillName="游龙惊风破"} }, |
| | | { HIDCode.H,new SkillInfo (){ Key=HIDCode.H,Range=new ZTSize (1280,720),WaitTime=180, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Quantity,ReleaseAnchor=SkillAnchor.Center,ReleaseTime=2000,SkillName="无限风域"} }, |
| | | { HIDCode.X,new SkillInfo (){ Key=HIDCode.X,Range=new ZTSize (200,170),WaitTime=0.5f, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Nearly,ReleaseAnchor=SkillAnchor.Side,ReleaseTime=500,SkillName="普通攻击"} }, |
| | | { HIDCode.Space,new SkillInfo (){ Key=HIDCode.Space,Range=new ZTSize (1280,720),WaitTime=300, AnchorOffset=new ZTSize(0,-50),MovePriority=MovePriority.Nearly,ReleaseAnchor=SkillAnchor.Center,ReleaseTime=2000,SkillName="技能加成"} } |
| | | }; |
| | | |
| | | /// <summary> |
| | | /// 获取技能 |
| | | /// </summary> |
| | | /// <param name="code"></param> |
| | | /// <returns></returns> |
| | | public static SkillInfo GetSkillInfo(HIDCode code) |
| | | { |
| | | if (Skills.ContainsKey(code)) |
| | | { |
| | | return Skills[code]; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 技能触发键 |
| | | /// </summary> |
| | | public HIDCode Key; |
| | | |
| | | /// <summary> |
| | | /// 攻击范围 |
| | | /// </summary> |
| | | public ZTSize Range; |
| | | |
| | | /// <summary> |
| | | /// 释放后需要等多少秒 |
| | | /// </summary> |
| | | public float WaitTime; |
| | | |
| | | /// <summary> |
| | | /// 技能名称 |
| | | /// </summary> |
| | | public string SkillName; |
| | | |
| | | /// <summary> |
| | | /// 技能释放时长 |
| | | /// </summary> |
| | | public float ReleaseTime { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 技能释放锚点 |
| | | /// </summary> |
| | | public SkillAnchor ReleaseAnchor { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 技能释放锚点编移 |
| | | /// 靠近为正,远离为负 |
| | | /// 上负,下正 |
| | | /// 锚点为中间时无效 |
| | | /// </summary> |
| | | public ZTSize AnchorOffset { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 移动优先级 |
| | | /// </summary> |
| | | public MovePriority MovePriority { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 技能释放锚点枚举 |
| | | /// </summary> |
| | | public enum SkillAnchor |
| | | { |
| | | Side, |
| | | Center |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | using RichCreator.Utility.InputControl; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Skills |
| | | { |
| | | /// <summary> |
| | | /// 技能释放队列 |
| | | /// </summary> |
| | | public class SkillQueue |
| | | { |
| | | private List<SKillCallTime> callTimes = new List<SKillCallTime>();//可调用的技能列表 |
| | | private SkillInfo lastSkill = null;//最后一个调用的技能 |
| | | private DateTime lastSkillCallTime = DateTime.MinValue;//最后一个技能的调用时间 |
| | | |
| | | public SkillQueue() |
| | | { |
| | | } |
| | | |
| | | public SkillQueue(HIDCode[] skillCodes) |
| | | { |
| | | for (int i = 0; i < skillCodes.Length; i++) |
| | | { |
| | | EnQueue(false, skillCodes[i]); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 向可队列添加技能 |
| | | /// </summary> |
| | | /// <param name="isOnce"></param> |
| | | /// <param name="skillCode"></param> |
| | | public void EnQueue(bool isOnce, HIDCode skillCode) |
| | | { |
| | | SkillInfo skill = SkillInfo.GetSkillInfo(skillCode); |
| | | SKillCallTime time = new SKillCallTime(skill,isOnce); |
| | | this.callTimes.Add(time); |
| | | } |
| | | |
| | | |
| | | private SkillInfo nextSkill; |
| | | |
| | | /// <summary> |
| | | /// 阻塞查看队列,但不从队列中删除 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public SkillInfo SyncPeek() |
| | | { |
| | | if (nextSkill == null) |
| | | { |
| | | nextSkill = FindOk(); |
| | | } |
| | | |
| | | return nextSkill; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 阻塞出队列 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public SkillInfo SyncDeQueue() |
| | | { |
| | | SkillInfo result = null; |
| | | if (nextSkill != null) |
| | | { |
| | | result = nextSkill; |
| | | nextSkill = null; |
| | | } |
| | | else |
| | | { |
| | | result = FindOk(); |
| | | } |
| | | |
| | | for (int i = 0; i < this.callTimes.Count; i++) |
| | | { |
| | | if (this.callTimes[i].Skill == result) |
| | | { |
| | | this.callTimes[i].CallCount++; |
| | | this.callTimes[i].LastCallTime = DateTime.Now; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 查找可以调用的技能 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private SkillInfo FindOk() |
| | | { |
| | | SKillCallTime callTime = null; |
| | | while (true) |
| | | { |
| | | for (int i = 0; i < callTimes.Count; i++) |
| | | { |
| | | callTime = callTimes[i]; |
| | | double dimMS = (DateTime.Now - callTime.LastCallTime).TotalMilliseconds; |
| | | if (dimMS > (callTime.Skill.WaitTime * 1000)) |
| | | { |
| | | //已经过了技能等待时间 |
| | | if (!callTime.IsOnce || callTime.CallCount <= 0) |
| | | { |
| | | //不是限制只调用一次,或一次也没调用过 |
| | | return callTime.Skill; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | //Thread.Sleep(100); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 技能调用时间 |
| | | /// </summary> |
| | | private class SKillCallTime |
| | | { |
| | | public SKillCallTime( SkillInfo skill,bool isOnce) |
| | | { |
| | | this.Skill = skill; |
| | | this.IsOnce = isOnce; |
| | | this.LastCallTime = DateTime.MinValue; |
| | | this.CallCount = 0; |
| | | } |
| | | /// <summary> |
| | | /// 技能 |
| | | /// </summary> |
| | | public SkillInfo Skill; |
| | | |
| | | /// <summary> |
| | | /// 上次调用时间 |
| | | /// </summary> |
| | | public DateTime LastCallTime; |
| | | |
| | | /// <summary> |
| | | /// 是否只能调用一次 |
| | | /// </summary> |
| | | public bool IsOnce; |
| | | |
| | | /// <summary> |
| | | /// 调用次数 |
| | | /// </summary> |
| | | public Int32 CallCount; |
| | | } |
| | | } |
| | | } |
| | |
| | | using System; |
| | | using RichCreator.Utility.Maps; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | |
| | | { |
| | | public HousePathInfoObj() |
| | | { |
| | | |
| | | this.NextGates = new List<ParametersPointObj>(); |
| | | this.PathGuides = new List<ZTTargetPolygonObj>(); |
| | | } |
| | | public HousePathInfoObj(Int32 width, Int32 height) |
| | | { |
| | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 循逻线 |
| | | /// 巡逻点 |
| | | /// </summary> |
| | | public List<ZTLinePointObj> LoopLines { get; set; } |
| | | public ZTPointObj LoopPoint { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 寻路线 |
| | | /// </summary> |
| | | public List<ZTLinePointObj> FindPathLines { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 下一关进门点 |
| | | /// 参数意义 0:上 1:右 2:下 3:左 |
| | | /// </summary> |
| | | public List<ParametersPointObj> NextGates { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 路径向导,把某一区域的点导向某一点 |
| | | /// </summary> |
| | | public List<ZTTargetPolygonObj> PathGuides { get; set; } |
| | | |
| | | public HousePathInfo To() |
| | | { |
| | |
| | | info.FindPathPoints.Add(item.To()); |
| | | } |
| | | |
| | | info.LoopLines = new List<ZTLinePoint>(); |
| | | foreach (var item in this.LoopLines) |
| | | if (this.LoopPoint == null) |
| | | { |
| | | info.LoopLines.Add(item.To()); |
| | | info.LoopPoint = ZTPoint.Empty; |
| | | } |
| | | else |
| | | { |
| | | info.LoopPoint = this.LoopPoint.To(); |
| | | } |
| | | |
| | | |
| | | info.FindPathLines = new List<ZTLinePoint>(); |
| | | foreach (var item in this.FindPathLines) |
| | | { |
| | | info.FindPathLines.Add(item.To()); |
| | | } |
| | | |
| | | info.NextGates = new List<ParametersPoint>(); |
| | | foreach (var item in this.NextGates) |
| | | { |
| | | info.NextGates.Add(item.To()); |
| | | } |
| | | |
| | | info.PathGuides = new List<ZTTargetPolygon>(); |
| | | foreach (var item in this.PathGuides) |
| | | { |
| | | info.PathGuides.Add(item.To()); |
| | | } |
| | | |
| | | |
| | | return info; |
| | | } |
| | |
| | | infoObj.FindPathPoints.Add(ZTPointObj.From(item)); |
| | | } |
| | | |
| | | infoObj.LoopLines = new List<ZTLinePointObj>(); |
| | | foreach (var item in info.LoopLines) |
| | | { |
| | | infoObj.LoopLines.Add(ZTLinePointObj.From(item)); |
| | | } |
| | | infoObj.LoopPoint = ZTPointObj.From(info.LoopPoint); |
| | | |
| | | infoObj.FindPathLines = new List<ZTLinePointObj>(); |
| | | foreach (var item in info.FindPathLines) |
| | |
| | | infoObj.FindPathLines.Add(ZTLinePointObj.From(item)); |
| | | } |
| | | |
| | | infoObj.NextGates = new List<ParametersPointObj>(); |
| | | foreach (var item in info.NextGates) |
| | | { |
| | | infoObj.NextGates.Add(ParametersPointObj.From(item)); |
| | | } |
| | | |
| | | |
| | | infoObj.PathGuides = new List<ZTTargetPolygonObj>(); |
| | | foreach (var item in info.PathGuides) |
| | | { |
| | | infoObj.PathGuides.Add(ZTTargetPolygonObj.From(item)); |
| | | } |
| | | |
| | | |
| | | return infoObj; |
| | | |
| | |
| | | /// <summary> |
| | | /// 带参数的点 |
| | | /// </summary> |
| | | public struct ParametersPoint |
| | | public struct ParametersPoint:IEquatable<ParametersPoint> |
| | | { |
| | | public readonly static ParametersPoint Empty = new ParametersPoint(ZTPoint.Empty, -1); |
| | | |
| | | public ParametersPoint(ZTPoint point, Int32 number) |
| | | { |
| | | this.Point = point; |
| | |
| | | /// </summary> |
| | | public Int32 Parameter { get; set; } |
| | | |
| | | public bool Equals(ParametersPoint other) |
| | | { |
| | | if (other.Point.Equals(this.Point) && other.Parameter == this.Parameter) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | |
| | | return new ZTPoint(this.X + val.X, this.Y + val.Y); |
| | | } |
| | | |
| | | public ZTPoint Add(Int32 x, Int32 y) |
| | | { |
| | | return new ZTPoint(this.X + x, this.Y + y); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 两个坐标相减 |
| | | /// </summary> |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Structs |
| | | { |
| | | /// <summary> |
| | | /// 有目标的多边形 |
| | | /// </summary> |
| | | public struct ZTTargetPolygon : IEquatable<ZTTargetPolygon> |
| | | { |
| | | public ZTTargetPolygon(ZTPolygon polygon,ZTPoint target) |
| | | { |
| | | this.Polygon = polygon; |
| | | this.Target = target; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 多边形 |
| | | /// </summary> |
| | | public ZTPolygon Polygon; |
| | | |
| | | /// <summary> |
| | | /// 目标点 |
| | | /// </summary> |
| | | public ZTPoint Target; |
| | | |
| | | |
| | | public bool Equals(ZTTargetPolygon other) |
| | | { |
| | | if (this.Polygon.Equals(other.Polygon) && this.Target.Equals(other.Target)) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Structs |
| | | { |
| | | public class ZTTargetPolygonObj |
| | | { |
| | | public ZTTargetPolygonObj() |
| | | { |
| | | |
| | | } |
| | | public ZTTargetPolygonObj(ZTPolygonObj polygon,ZTPointObj target) |
| | | { |
| | | this.Polygon = polygon; |
| | | this.Target = target; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 多边形 |
| | | /// </summary> |
| | | public ZTPolygonObj Polygon { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 目标点 |
| | | /// </summary> |
| | | public ZTPointObj Target { get; set; } |
| | | |
| | | |
| | | public ZTTargetPolygon To() |
| | | { |
| | | |
| | | ZTPolygon polygon=this.Polygon.To(); |
| | | ZTPoint target = this.Target.To(); |
| | | return new ZTTargetPolygon(polygon, target); |
| | | } |
| | | |
| | | public static ZTTargetPolygonObj From(ZTTargetPolygon obj) |
| | | { |
| | | ZTPolygonObj polygon = ZTPolygonObj.From(obj.Polygon); |
| | | ZTPointObj target = ZTPointObj.From(obj.Target); |
| | | |
| | | return new ZTTargetPolygonObj(polygon, target); |
| | | } |
| | | } |
| | | } |
| | |
| | | /// 按键时,键盘按下和弹起的时间间隔最小值 |
| | | /// </summary> |
| | | public const Int32 KeyPressDurationMin = 80; |
| | | //public const Int32 KeyPressDurationMin = 30; |
| | | |
| | | /// <summary> |
| | | /// 按键时,键盘按下和弹起的时间间隔最大值 |
| | | /// </summary> |
| | | public const Int32 KeyPressDurationMax = 176; |
| | | //public const Int32 KeyPressDurationMax = 35; |
| | | |
| | | /// <summary> |
| | | /// 让点在范围内随机 |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Runtime.InteropServices; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Windows.Forms; |
| | | |
| | | namespace RichCreator.Utility.Utilitys |
| | | { |
| | | public class SystemHotKey |
| | | { |
| | | /// <summary> |
| | | /// 如果函数执行成功,返回值不为0。 |
| | | /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。 |
| | | /// </summary> |
| | | /// <param name="hWnd">要定义热键的窗口的句柄</param> |
| | | /// <param name="id">定义热键ID(不能与其它ID重复)</param> |
| | | /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param> |
| | | /// <param name="vk">定义热键的内容</param> |
| | | /// <returns></returns> |
| | | [DllImport("user32.dll", SetLastError = true)] |
| | | public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk); |
| | | |
| | | /// <summary> |
| | | /// 注销热键 |
| | | /// </summary> |
| | | /// <param name="hWnd">要取消热键的窗口的句柄</param> |
| | | /// <param name="id">要取消热键的ID</param> |
| | | /// <returns></returns> |
| | | [DllImport("user32.dll", SetLastError = true)] |
| | | public static extern bool UnregisterHotKey(IntPtr hWnd, int id); |
| | | |
| | | /// <summary> |
| | | /// 辅助键名称。 |
| | | /// Alt, Ctrl, Shift, WindowsKey |
| | | /// </summary> |
| | | [Flags()] |
| | | public enum KeyModifiers { None = 0, Alt = 1, Ctrl = 2, Shift = 4, WindowsKey = 8 } |
| | | |
| | | /// <summary> |
| | | /// 注册热键 |
| | | /// </summary> |
| | | /// <param name="hwnd">窗口句柄</param> |
| | | /// <param name="hotKey_id">热键ID</param> |
| | | /// <param name="keyModifiers">组合键</param> |
| | | /// <param name="key">热键</param> |
| | | public static bool RegHotKey(IntPtr hwnd, int hotKeyId, KeyModifiers keyModifiers, Keys key) |
| | | { |
| | | if (!RegisterHotKey(hwnd, hotKeyId, keyModifiers, key)) |
| | | { |
| | | int errorCode = Marshal.GetLastWin32Error(); |
| | | //if (errorCode == 1409) |
| | | //{ |
| | | // MessageBox.Show("热键被占用 !"); |
| | | //} |
| | | //else |
| | | //{ |
| | | // MessageBox.Show("注册热键失败!错误代码:" + errorCode); |
| | | //} |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 注销热键 |
| | | /// </summary> |
| | | /// <param name="hwnd">窗口句柄</param> |
| | | /// <param name="hotKey_id">热键ID</param> |
| | | public static void UnRegHotKey(IntPtr hwnd, int hotKeyId) |
| | | { |
| | | //注销指定的热键 |
| | | UnregisterHotKey(hwnd, hotKeyId); |
| | | } |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility |
| | | { |
| | | //结果 |
| | | public enum ZTResult:Int32 |
| | | { |
| | | Failed=0,//失败 |
| | | Success=1,//成功 |
| | | Timeout=2,//超时 |
| | | Cancel=3//取消 |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Dnf; |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Threading; |
| | | |
| | | |
| | | namespace RichCreator.Dnf |
| | | { |
| | | /// <summary> |
| | | /// DNF角色 |
| | | /// </summary> |
| | | public class DnfRole |
| | | { |
| | | |
| | | private SpeedProvider speed;//速度 |
| | | |
| | | private const Int32 PaddingLeft = 140;//左边框内边距 |
| | | private const Int32 PaddingRight = 140;//右边框内边距 |
| | | |
| | | public DnfRole(ZTRectangle gameRect) |
| | | { |
| | | this.gameRect = gameRect; |
| | | speed = SpeedProvider.Define; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | private Int32 minCenterLineY; |
| | | private Int32 maxCenterLineY; |
| | | private Int32 centerLineErrorRange = 35;//中间性可允许的误差 |
| | | |
| | | private HouseInfo house; |
| | | private ZTRectangle gameRect = ZTRectangle.Empty; |
| | | |
| | | |
| | | private MoveIntent movingIntent = MoveIntent.AttackMove;//移动意图 |
| | | private MoveMethod movingMethod = MoveMethod.Vertical;//移动方式,默认垂直移动 |
| | | private ZTSize movingDistance;//移动距离 |
| | | |
| | | |
| | | public ZTPoint Position { get; private set; }//角色位置 |
| | | |
| | | /// <summary> |
| | | /// 按下的键,0:横向,1:纵向 |
| | | /// </summary> |
| | | private HIDCode[] pressKeys = new HIDCode[] { HIDCode.NoEvent, HIDCode.NoEvent };//当前按键 |
| | | private bool isRun = false;//是否奔跑 |
| | | |
| | | /// <summary> |
| | | /// 设置当前房间信息 |
| | | /// </summary> |
| | | /// <param name="house"></param> |
| | | public void SetHouse(HouseInfo house) |
| | | { |
| | | this.house = house; |
| | | minCenterLineY = this.gameRect.End.Y + this.house.HouseCenterMoveLine - centerLineErrorRange; |
| | | maxCenterLineY = this.gameRect.End.Y + this.house.HouseCenterMoveLine + centerLineErrorRange; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置当前角色速度 |
| | | /// </summary> |
| | | /// <param name="speed"></param> |
| | | public void SetSpeed(Int32 speed) |
| | | { |
| | | this.speed = new SpeedProvider(speed); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 更新位置 |
| | | /// </summary> |
| | | /// <param name="position"></param> |
| | | public void UpdatePosition(ZTPoint position) |
| | | { |
| | | this.Position = position; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 是否移动中 |
| | | /// </summary> |
| | | public bool IsMoving |
| | | { |
| | | get |
| | | { |
| | | return pressKeys[0] != HIDCode.NoEvent || pressKeys[1] != HIDCode.NoEvent; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否指定移动行为 |
| | | /// </summary> |
| | | /// <param name="intent"></param> |
| | | /// <returns></returns> |
| | | public bool IsMoveIntent(MoveIntent intent) |
| | | { |
| | | if (IsMoving && movingIntent == intent) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 攻击移动 |
| | | /// </summary> |
| | | /// <param name="moveDistance"></param> |
| | | public void AttackMove(ZTSize moveDistance) |
| | | { |
| | | PutKey(moveDistance); |
| | | movingIntent = MoveIntent.AttackMove; |
| | | } |
| | | |
| | | private Int32 findRoleDir = 0;//寻找角色行走的方向 |
| | | private DateTime findRoleMoveTimeout = DateTime.MinValue;//方向移动过期时间 |
| | | |
| | | private static HIDCode[][] dir = new HIDCode[][] { new HIDCode[] { HIDCode.LeftArrow ,HIDCode.NoEvent}, new HIDCode[] { HIDCode.NoEvent, HIDCode.UpArrow }, new HIDCode[] { HIDCode.RightArrow, HIDCode.NoEvent }, new HIDCode[] { HIDCode.NoEvent, HIDCode.DownArrow } }; |
| | | |
| | | |
| | | /// <summary> |
| | | /// 查找主角移动 |
| | | /// </summary> |
| | | /// <param name="moveDistance"></param> |
| | | public void FindRoleMove() |
| | | { |
| | | if (IsMoving && !IsMoveIntent(MoveIntent.FindRoleMove)) |
| | | { |
| | | StopMove(); |
| | | } |
| | | |
| | | if (DateTime.Now >= findRoleMoveTimeout) |
| | | { |
| | | //转换方向 |
| | | findRoleDir++; |
| | | HIDCode[] tempKeys = dir[findRoleDir % 4]; |
| | | Int32 stepms = 0, runms = 0; |
| | | PutKey(out stepms, out runms, tempKeys[0], tempKeys[1], true); |
| | | findRoleMoveTimeout = DateTime.Now.AddMilliseconds(speed.RandomMoveMillSecond); |
| | | } |
| | | |
| | | //if (!IsMoving || (IsMoving && KeyIsChange(tempKeys))) |
| | | //{ |
| | | // //Int32 stepms = 0, runms = 0; |
| | | // //PutKey(out stepms, out runms, tempKeys[0], tempKeys[1], true); |
| | | //} |
| | | movingIntent = MoveIntent.FindRoleMove; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 拾起物品移动 |
| | | /// </summary> |
| | | public void PickupMove(ZTPoint rolePosition, ZTPoint thingItemPosition) |
| | | { |
| | | ZTSize moveDistance = new ZTSize(thingItemPosition.X - rolePosition.X, thingItemPosition.Y - rolePosition.Y - 97); |
| | | if (Math.Abs(moveDistance.Width) < 100 && Math.Abs(moveDistance.Height) < 100) |
| | | { |
| | | //距离允许,就近距离移动并X |
| | | G.Instance.DebugWriter("distance ok"); |
| | | SyncMove(new ZTPoint(moveDistance.Width,moveDistance.Height)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.G(400, 500), HIDCode.X); |
| | | return; |
| | | } |
| | | |
| | | //G.Instance.DebugWriter("pickup distance:" + moveDistance.ToString()); |
| | | PutKey(moveDistance); |
| | | movingIntent = MoveIntent.PickupMove; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 找门移动 |
| | | /// </summary> |
| | | /// <param name="rolePosition"></param> |
| | | public void FindDoorMove(ZTPoint rolePosition) |
| | | { |
| | | ComputeMoveInfo(rolePosition); |
| | | |
| | | HIDCode dirKey = HIDCode.NoEvent; |
| | | switch (movingMethod) |
| | | { |
| | | case MoveMethod.ToLeft: |
| | | dirKey = HIDCode.LeftArrow; |
| | | break; |
| | | case MoveMethod.ToRight: |
| | | dirKey = HIDCode.RightArrow; |
| | | break; |
| | | case MoveMethod.Vertical: |
| | | dirKey = movingDistance.Height > 0 ? HIDCode.DownArrow : HIDCode.UpArrow; |
| | | break; |
| | | case MoveMethod.Fixed: |
| | | SyncMove(new ZTPoint(movingDistance.Width,movingDistance.Height)); |
| | | StopMove(); |
| | | return; |
| | | } |
| | | |
| | | PutKey(movingDistance); |
| | | movingIntent = MoveIntent.FindDoorMove; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 同步移动指定距离 |
| | | /// </summary> |
| | | /// <param name="distance"></param> |
| | | public void SyncMove(ZTPoint size) |
| | | { |
| | | ZTSize distance = new ZTSize(size.X, size.Y); |
| | | HIDCode horizontal = HIDCode.NoEvent; |
| | | HIDCode vertical = HIDCode.NoEvent; |
| | | bool isRun = false; |
| | | int runms, stepms; |
| | | Int32 xsig = Math.Sign(distance.Width); |
| | | Int32 ysig = Math.Sign(distance.Height); |
| | | |
| | | if (Math.Abs(distance.Width) >= speed.RunThresold) |
| | | { |
| | | isRun = true; |
| | | } |
| | | |
| | | if (distance.Height > 0) |
| | | { |
| | | vertical = HIDCode.DownArrow; |
| | | } |
| | | |
| | | if (distance.Height < 0) |
| | | { |
| | | vertical = HIDCode.UpArrow; |
| | | } |
| | | |
| | | if (distance.Width > 0) |
| | | { |
| | | horizontal = HIDCode.RightArrow; |
| | | } |
| | | |
| | | if (distance.Width < 0) |
| | | { |
| | | horizontal = HIDCode.LeftArrow; |
| | | } |
| | | |
| | | PutKey(out stepms, out runms, horizontal, vertical, isRun); |
| | | if (stepms > 0) |
| | | { |
| | | Int32 mdistance = (Int32)(stepms * speed.StepX); |
| | | if (runms > 0) |
| | | { |
| | | mdistance += (Int32)(runms * speed.RunX); |
| | | } |
| | | distance = new ZTSize(distance.Width - xsig * mdistance, distance.Height); |
| | | } |
| | | |
| | | int ytime = (Int32)(Math.Abs(distance.Height) / speed.StepY); |
| | | Int32 xtime = (Int32)(Math.Abs(distance.Width) / speed.StepX); |
| | | if (isRun) |
| | | { |
| | | xtime = (Int32)(Math.Abs(distance.Width) / speed.RunX); |
| | | } |
| | | |
| | | |
| | | |
| | | Int32 mintime = Math.Min(xtime, ytime); |
| | | if (xtime <= 0) |
| | | { |
| | | mintime = ytime; |
| | | } |
| | | if (ytime <= 0) |
| | | { |
| | | mintime = xtime; |
| | | } |
| | | Thread.Sleep(mintime); |
| | | |
| | | xtime -= mintime; |
| | | ytime -= mintime; |
| | | if (xtime > 0) |
| | | { |
| | | PutKey(out stepms, out runms, horizontal, HIDCode.NoEvent, isRun); |
| | | Thread.Sleep(xtime); |
| | | } |
| | | if (ytime > 0) |
| | | { |
| | | PutKey(out stepms, out runms, HIDCode.NoEvent, vertical, false); |
| | | Thread.Sleep(ytime); |
| | | } |
| | | StopMove(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 停止移动 |
| | | /// </summary> |
| | | public void StopMove() |
| | | { |
| | | if (IsMoving) |
| | | { |
| | | //停止 |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | pressKeys[0] = HIDCode.NoEvent; |
| | | pressKeys[1] = HIDCode.NoEvent; |
| | | isRun = false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 休眠 |
| | | /// </summary> |
| | | /// <param name="millSecond"></param> |
| | | public void Sleep(Int32 millSecond) |
| | | { |
| | | Thread.Sleep(millSecond); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 释放技能 |
| | | /// </summary> |
| | | public void ReleaseSkill(HIDCode key) |
| | | { |
| | | ReleaseSkill(key, 0); |
| | | } |
| | | |
| | | |
| | | public void ReleaseSkill(HIDCode key, Int32 skillTimeout) |
| | | { |
| | | Int32 dur = RandomUtils.KeyPressDuration; |
| | | G.Instance.InputControl.PressKey(dur,key); |
| | | Int32 subTime = skillTimeout - dur; |
| | | if (subTime > 0) |
| | | { |
| | | Thread.Sleep(subTime); |
| | | } |
| | | } |
| | | |
| | | private ZTPoint roleLastPosition = ZTPoint.Empty; |
| | | private bool StaticTimerIsStart = false;//静止计时是否开始 |
| | | private Int32 StaticTimerCounter = 0;//静止计时计数器 |
| | | private DateTime DetectLastNoMoveTime = DateTime.MaxValue;//最后没移动时间 |
| | | private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数 |
| | | |
| | | /// <summary> |
| | | /// 得到循环移动的距离 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private void ComputeMoveInfo(ZTPoint rolePosition) |
| | | { |
| | | ZTRectangle limitRect = ZTRectangle.Empty; |
| | | |
| | | //达到未移动阀值,可能有障碍物,先攻击,如果攻击后还是无效则上下左右移 |
| | | if (rolePosition.Equals(this.roleLastPosition)) |
| | | { |
| | | if (StaticTimerIsStart) |
| | | { |
| | | if ((DateTime.Now - DetectLastNoMoveTime).TotalMilliseconds > NoMoveMaxMillSecond) |
| | | { |
| | | G.Instance.DebugWriter($"find door not move,role position:{rolePosition.ToString()}"); |
| | | this.StopMove(); |
| | | if (StaticTimerCounter == 0) |
| | | { |
| | | //清除障碍物 |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X); |
| | | } |
| | | else |
| | | { |
| | | //无法清除障碍物,随机移动一下 |
| | | switch (StaticTimerCounter % 4) |
| | | { |
| | | case 0: |
| | | G.Instance.DebugWriter("random up"); |
| | | //上 |
| | | movingDistance = new ZTSize(0, -300); |
| | | break; |
| | | case 1: |
| | | //右 |
| | | movingDistance = new ZTSize(600, 0); |
| | | |
| | | break; |
| | | case 2: |
| | | //下 |
| | | movingDistance = new ZTSize(0, 300); |
| | | break; |
| | | case 3: |
| | | //左 |
| | | movingDistance = new ZTSize(-600, 0); |
| | | break; |
| | | } |
| | | |
| | | movingMethod = MoveMethod.Fixed; |
| | | } |
| | | StaticTimerCounter++; |
| | | DetectLastNoMoveTime = DateTime.Now; |
| | | if (StaticTimerCounter > 1) |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | } |
| | | else if (!StaticTimerIsStart) |
| | | { |
| | | //没开始计时 则 开始计时 |
| | | StaticTimerIsStart = true; |
| | | DetectLastNoMoveTime = DateTime.Now; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //移动了 取消计时 |
| | | this.roleLastPosition = rolePosition; |
| | | StaticTimerIsStart = false; |
| | | StaticTimerCounter = 0; |
| | | } |
| | | |
| | | if (!IsMoving) |
| | | { |
| | | //刚开始移动 |
| | | movingMethod = MoveMethod.Vertical; |
| | | } |
| | | |
| | | if (movingMethod == MoveMethod.Vertical && rolePosition.Y >= minCenterLineY && rolePosition.Y <= maxCenterLineY) |
| | | { |
| | | //不需要上下移动,计算左右 |
| | | if (this.house.DoorDirection[0] == Direction.Left) |
| | | { |
| | | movingMethod = MoveMethod.ToLeft; |
| | | } |
| | | else if (this.house.DoorDirection[0] == Direction.Right) |
| | | { |
| | | movingMethod = MoveMethod.ToRight; |
| | | } |
| | | else |
| | | { |
| | | //计算是向左还是右,哪边大往哪边 |
| | | if (rolePosition.X > (this.gameRect.Start.X + (this.gameRect.End.X - this.gameRect.Start.X) / 2)) |
| | | { |
| | | //左边空间大 |
| | | movingMethod = MoveMethod.ToLeft; |
| | | } |
| | | else |
| | | { |
| | | movingMethod = MoveMethod.ToRight; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (movingMethod == MoveMethod.ToLeft) |
| | | { |
| | | //计算左边界范围 |
| | | limitRect = new ZTRectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.Start.X + PaddingLeft, gameRect.End.Y); |
| | | //判断是否到左边界 |
| | | |
| | | if (RichCreator.Utilitys.Utils.IsInRect(rolePosition, limitRect)) |
| | | { |
| | | //到左边界就向右走 |
| | | movingMethod = MoveMethod.ToRight; |
| | | movingDistance = new ZTSize(gameRect.End.X - rolePosition.X, 0); |
| | | } |
| | | else |
| | | { |
| | | //没到继续向左走 |
| | | movingMethod = MoveMethod.ToLeft; |
| | | movingDistance = new ZTSize(limitRect.Start.X - rolePosition.X, 0); |
| | | } |
| | | } |
| | | else if (movingMethod == MoveMethod.ToRight) |
| | | { |
| | | //计算右边界范围 |
| | | limitRect = new ZTRectangle(gameRect.End.X - PaddingRight, gameRect.Start.Y, gameRect.End.X, gameRect.End.Y); |
| | | //判断是否到右边界 |
| | | if (Utilitys.Utils.IsInRect(rolePosition, limitRect)) |
| | | { |
| | | //到右边界就向左走 |
| | | G.Instance.InfoWriter($"in limit rect,role position:{rolePosition.ToString()},limit:{limitRect.ToString()}"); |
| | | movingMethod = MoveMethod.ToLeft; |
| | | movingDistance = new ZTSize(gameRect.Start.X - rolePosition.X, 0); |
| | | } |
| | | else |
| | | { |
| | | //没到继续向右走 |
| | | movingMethod = MoveMethod.ToRight; |
| | | movingDistance = new ZTSize(gameRect.End.X - rolePosition.X, 0); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //向点移动 |
| | | Int32 targetY = gameRect.End.Y + this.house.HouseCenterMoveLine; |
| | | movingDistance = new ZTSize(0, targetY - rolePosition.Y); |
| | | } |
| | | } |
| | | |
| | | #region 八方向移动 |
| | | /// <summary> |
| | | /// 按下按键 |
| | | /// </summary> |
| | | /// <param name="distance"></param> |
| | | private void PutKey(ZTSize distance) |
| | | { |
| | | HIDCode horizontal = HIDCode.NoEvent; |
| | | HIDCode vertical = HIDCode.NoEvent; |
| | | bool isRun = false; |
| | | if (distance.Width < 0) |
| | | { |
| | | horizontal = HIDCode.LeftArrow; |
| | | } |
| | | if (distance.Width > 0) |
| | | { |
| | | horizontal = HIDCode.RightArrow; |
| | | } |
| | | |
| | | if (Math.Abs(distance.Width) >= speed.RunThresold) |
| | | { |
| | | isRun = true; |
| | | } |
| | | |
| | | |
| | | if (distance.Height < 0) |
| | | { |
| | | vertical = HIDCode.UpArrow; |
| | | } |
| | | if (distance.Height > 0) |
| | | { |
| | | vertical = HIDCode.DownArrow; |
| | | } |
| | | |
| | | Int32 stepms, runms; |
| | | PutKey(out stepms, out runms, horizontal, vertical, isRun); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 行走按键 |
| | | /// </summary> |
| | | /// <param name="stepMS">已经步行ms</param> |
| | | /// <param name="runMS">已经奔跑ms</param> |
| | | /// <param name="horizontal">横向按键</param> |
| | | /// <param name="vertical">纵向按键</param> |
| | | /// <param name="isRun">是否奔跑</param> |
| | | private void PutKey(out Int32 stepMS, out Int32 runMS, HIDCode horizontal, HIDCode vertical, bool isRun) |
| | | { |
| | | stepMS = 0; |
| | | runMS = 0; |
| | | if (horizontal == vertical) |
| | | { |
| | | return; |
| | | } |
| | | if (horizontal == pressKeys[0] && vertical == pressKeys[1]) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | int keyCount = horizontal != HIDCode.NoEvent && vertical != HIDCode.NoEvent ? 2 : 1; |
| | | Int32 tempwait = 0; |
| | | if (isRun) |
| | | { |
| | | //跑 |
| | | if (!this.isRun || horizontal != pressKeys[0]) |
| | | { |
| | | //如果之前没有跑,或跑的方向不一样,则开始跑 |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal); |
| | | tempwait = RandomUtils.KeyPressDuration; |
| | | stepMS += tempwait; |
| | | Thread.Sleep(tempwait); |
| | | |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | Thread.Sleep(RandomUtils.KeyPressDuration); |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal); |
| | | this.isRun = true; |
| | | |
| | | if (keyCount == 2) |
| | | { |
| | | tempwait = RandomUtils.KeyPressDuration; |
| | | runMS += tempwait; |
| | | Thread.Sleep(tempwait); |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical); |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | //奔跑方向不变 |
| | | int afterKeyCount = pressKeys[0] != HIDCode.NoEvent && pressKeys[1] != HIDCode.NoEvent ? 2 : 1; |
| | | if (afterKeyCount != keyCount) |
| | | { |
| | | //如果跟原来按键数量不一样 |
| | | if (keyCount == 1) |
| | | { |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal); |
| | | } |
| | | else |
| | | { |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //走 |
| | | if (keyCount == 1) |
| | | { |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal != HIDCode.NoEvent ? horizontal : vertical); |
| | | } |
| | | else |
| | | { |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical); |
| | | } |
| | | |
| | | } |
| | | |
| | | pressKeys[0] = horizontal; |
| | | pressKeys[1] = vertical; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 按钮是否变化 |
| | | /// </summary> |
| | | /// <param name="pressKey"></param> |
| | | /// <returns></returns> |
| | | private bool KeyIsChange(HIDCode[] pressKey) |
| | | { |
| | | if (pressKey == null || pressKey.Length != 2) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | if (pressKeys[0] == pressKey[0] && pressKeys[1] == pressKey[1]) |
| | | { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Dnf |
| | | { |
| | | /// <summary> |
| | | /// 小地图 |
| | | /// </summary> |
| | | public abstract class IMiniMap |
| | | { |
| | | public ZTRectangle GameRect { get; private set; } |
| | | |
| | | public ZTPoint MinimapOffset { get; private set; } |
| | | |
| | | |
| | | |
| | | public IMiniMap(ZTRectangle gameRect,ZTPoint miniMapOffset) |
| | | { |
| | | this.GameRect = gameRect; |
| | | this.MinimapOffset = miniMapOffset.Add(gameRect.Start); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取房间号 |
| | | /// </summary> |
| | | /// <param name="houseIndex">房间号,以0开始</param> |
| | | /// <param name="image">图像,可以传空,传空则自获取</param> |
| | | /// <returns>true:获取成功,false:获取失败</returns> |
| | | public bool GetCurrentHouseIndex(out int houseIndex, Image<Rgb, byte> image) |
| | | { |
| | | if (image == null) |
| | | { |
| | | image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(this.GameRect.Start.X, this.GameRect.Start.Y, this.GameRect.End.X - this.GameRect.Start.X + 1, this.GameRect.End.Y - this.GameRect.Start.Y + 1)); |
| | | } |
| | | return GetCurrentHouse(out houseIndex, image); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 在超时之前获取房间号 |
| | | /// </summary> |
| | | /// <param name="houseIndex">房间号,以0开始</param> |
| | | /// <param name="image">图像,可以传空,传空则自获取</param> |
| | | /// <param name="timeoutMillSecond">超时毫秒数</param> |
| | | /// <returns>true:获取成功,false:获取失败</returns> |
| | | public bool GetCurrentHouseIndexWaitTimeout(out int houseIndex, Image<Rgb, byte> image, CancellationToken cancelToken, Int32 timeoutMillSecond) |
| | | { |
| | | houseIndex = 0; |
| | | Int32 houseid = -1; |
| | | if (image != null) |
| | | { |
| | | if (GetCurrentHouse(out houseid, image)) |
| | | { |
| | | houseIndex = houseid; |
| | | return true; |
| | | } |
| | | } |
| | | if (!FuncUtils.TimeoutCancelableWrap(timeoutMillSecond, cancelToken, () => |
| | | { |
| | | using (System.Drawing.Bitmap bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(this.GameRect.Start.X, this.GameRect.Start.Y, this.GameRect.End.X - this.GameRect.Start.X + 1, this.GameRect.End.Y - this.GameRect.Start.Y + 1)); |
| | | return GetCurrentHouse(out houseid, image); |
| | | } |
| | | }, 50)) |
| | | { |
| | | return false; |
| | | } |
| | | houseIndex = houseid; |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 计算当前房间号 |
| | | /// </summary> |
| | | /// <param name="houseIndex"></param> |
| | | /// <param name="image"></param> |
| | | /// <returns></returns> |
| | | protected abstract bool GetCurrentHouse(out Int32 houseIndex, Image<Rgb, byte> image); |
| | | } |
| | | } |
| New file |
| | |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Dnf |
| | | { |
| | | /// <summary> |
| | | /// 地图信息 |
| | | /// </summary> |
| | | public abstract class MapInfo |
| | | { |
| | | public MapInfo(MapType mapType, ZTRectangle gameRect, CancellationToken cancellationToken) |
| | | { |
| | | this.MapType = mapType; |
| | | this.GameRect = gameRect; |
| | | this.CancelToken = cancellationToken; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 游戏区域 |
| | | /// </summary> |
| | | public ZTRectangle GameRect { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 小地图 |
| | | /// </summary> |
| | | public IMiniMap MiniMap { get; set; } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 取消令牌 |
| | | /// </summary> |
| | | public CancellationToken CancelToken { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 地图类型 |
| | | /// </summary> |
| | | public MapType MapType { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 开始刷图 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public abstract ZTResult Start(Int32 runningStep); |
| | | |
| | | |
| | | /// <summary> |
| | | /// 是否已进入地图 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public virtual bool IsEntryMap() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 进入每个房间后的前置工作 |
| | | /// </summary> |
| | | /// <param name="houseIndex"></param> |
| | | /// <param name="preHouseIndex"></param> |
| | | public virtual void EntryHousePrework(Int32 houseIndex, Int32 preHouseIndex) |
| | | { } |
| | | } |
| | | } |
| | |
| | | using System.Threading.Tasks; |
| | | using ZTImage.Configuration; |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Maps.Kalete; |
| | | using RichCreator.Maps.Lindong; |
| | | using RichCreator.Maps.SkillSetting; |
| | | using RichCreator.Maps.Test; |
| | | using RichCreator.Dnf; |
| | | |
| | | namespace RichCreator.Jobs |
| | | { |
| | | public class DNFJob<T> : JobBase where T:MapInfo,new() |
| | | public class DNFJob : JobBase |
| | | { |
| | | public DNFJob(RichCreatorConfig config) : base(config) |
| | | { } |
| | | public DNFJob(MapType mapType,RichCreatorConfig config) : base(config) |
| | | { |
| | | this.MapType = mapType; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 选角色时的角色选择偏移 |
| | | /// </summary> |
| | | private static Utility.Structs.ZTPoint[] RoleOffset = new Utility.Structs.ZTPoint[] { |
| | | new Utility.Structs.ZTPoint (154,225), |
| | | new Utility.Structs.ZTPoint (300,225), |
| | | new Utility.Structs.ZTPoint (443,225), |
| | | new Utility.Structs.ZTPoint (593,225), |
| | | new Utility.Structs.ZTPoint (726,225), |
| | | new Utility.Structs.ZTPoint (883,225), |
| | | private static ZTPoint[] RoleOffset = new Utility.Structs.ZTPoint[] { |
| | | new ZTPoint (154,225), |
| | | new ZTPoint (300,225), |
| | | new ZTPoint (443,225), |
| | | new ZTPoint (593,225), |
| | | new ZTPoint (726,225), |
| | | new ZTPoint (883,225), |
| | | |
| | | new Utility.Structs.ZTPoint (154,455), |
| | | new Utility.Structs.ZTPoint (300,455), |
| | | new Utility.Structs.ZTPoint (443,455), |
| | | new Utility.Structs.ZTPoint (593,455), |
| | | new Utility.Structs.ZTPoint (726,455), |
| | | new Utility.Structs.ZTPoint (883,455) |
| | | new ZTPoint (154,455), |
| | | new ZTPoint (300,455), |
| | | new ZTPoint (443,455), |
| | | new ZTPoint (593,455), |
| | | new ZTPoint (726,455), |
| | | new ZTPoint (883,455) |
| | | }; |
| | | |
| | | /// <summary> |
| | | /// 游戏窗口 |
| | | /// </summary> |
| | | private ZTRectangle GameRect; |
| | | public ZTRectangle GameRect; |
| | | |
| | | /// <summary> |
| | | /// 地图类型 |
| | | /// </summary> |
| | | public MapType MapType { get; private set; } |
| | | |
| | | private Int32 runningStep = 0; |
| | | |
| | |
| | | if (pilaozhi > 0) |
| | | { |
| | | //刷图,并保持在可按esc退出的状态 |
| | | MapInfo map = new T(); |
| | | mapResult = map.Start(this.GameRect, cancellationToken,this.runningStep); |
| | | MapInfo map = CreateMap( cancellationToken); |
| | | mapResult = map.Start(this.runningStep); |
| | | } |
| | | runningStep = RunningStep.None; |
| | | |
| | |
| | | G.Instance.InfoWriter("退回选择角色界面失败"); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 根据当前选择的地图实例化DNF地图 |
| | | /// </summary> |
| | | /// <param name="config"></param> |
| | | /// <returns></returns> |
| | | private MapInfo CreateMap(CancellationToken cancelToken) |
| | | { |
| | | switch (this.MapType) |
| | | { |
| | | case MapType.Lingdong: |
| | | return new LindongMap(this.GameRect,cancelToken); |
| | | case MapType.Kalete: |
| | | return new KaleteMap(this.GameRect, cancelToken); |
| | | case MapType.SkillSetting: |
| | | return new SkillSettingMap(this.GameRect, cancelToken); |
| | | case MapType.Test: |
| | | return new TestMap(this.GameRect, cancelToken); |
| | | } |
| | | throw new Exception("this task index is error"); |
| | | } |
| | | } |
| | | } |
| | |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.InputControl; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | |
| | | using System.Threading.Tasks; |
| | | using ZTImage.Configuration; |
| | | using RichCreator.Maps; |
| | | using RichCreator.Utility.Maps; |
| | | |
| | | namespace RichCreator |
| | | { |
| | |
| | | private WeGameJob wegameJob; |
| | | private JobBase dnfJob; |
| | | |
| | | private Int32 taskIndex; |
| | | private MapType mapType; |
| | | |
| | | Int32 runningStep = RunningStep.None; |
| | | |
| | | public JobMonitor(Int32 taskIndex) |
| | | public JobMonitor(MapType maptype) |
| | | { |
| | | this.config = ConfigHelper.GetInstance<RichCreatorConfig>(); |
| | | this.cancelTokenSource = new CancellationTokenSource(); |
| | | this.taskIndex = taskIndex; |
| | | this.mapType = maptype; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | |
| | | //设为顶层 |
| | | WindowUtils.SetDnfToTop(); |
| | | this.dnfJob = GetDNFJob(); |
| | | this.dnfJob = new DNFJob(this.mapType, this.config); |
| | | jobResult = this.dnfJob.Do(this.cancelTokenSource.Token, runningStep); |
| | | if (jobResult != ZTResult.Success) |
| | | { |
| | |
| | | ProcessUtils.CloseWeGame(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据当前选择的地图实例化DNF地图 |
| | | /// </summary> |
| | | /// <param name="config"></param> |
| | | /// <returns></returns> |
| | | private JobBase GetDNFJob() |
| | | { |
| | | switch (this.taskIndex) |
| | | { |
| | | case 0: |
| | | return new DNFJob<LindongMap>(this.config); |
| | | case 1: |
| | | return new DNFJob<SkillMap>(this.config); |
| | | case 2: |
| | | return new DNFJob<TestMap>(this.config); |
| | | } |
| | | throw new Exception("this task index is error"); |
| | | } |
| | | } |
| | | } |
| | |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | using RichCreator.Utility; |
| | | |
| | | namespace RichCreator.Jobs |
| | | { |
| | |
| | | mc:Ignorable="d" |
| | | WindowStyle="SingleBorderWindow" |
| | | ResizeMode="NoResize" |
| | | Loaded="Window_Loaded" |
| | | Unloaded="Window_Unloaded" |
| | | Title="富豪自动创造机" Height="250" Width="800" WindowStartupLocation="CenterScreen"> |
| | | <Window.Resources> |
| | | <Style TargetType="Border" x:Key="RowBorderStyle"> |
| | |
| | | <Button Content="移动" Padding="15 0 15 0" Margin="5" Click="TestMoveClick" />--> |
| | | <ComboBox SelectedIndex="0" x:Name="taskName" VerticalAlignment="Center"> |
| | | <ComboBoxItem >凛冬</ComboBoxItem> |
| | | <ComboBoxItem >技能</ComboBoxItem> |
| | | <ComboBoxItem >卡勒特</ComboBoxItem> |
| | | <ComboBoxItem >技能设置</ComboBoxItem> |
| | | <ComboBoxItem >测试</ComboBoxItem> |
| | | <ComboBoxItem >测速</ComboBoxItem> |
| | | <ComboBoxItem >测技能</ComboBoxItem> |
| | | <ComboBoxItem>读角色位置</ComboBoxItem> |
| | | <ComboBoxItem>移动进门</ComboBoxItem> |
| | | </ComboBox> |
| | | <Button Content="清空" Padding="15 0 15 0" Margin="5" Click="ClearLog_Click" /> |
| | | <Button Content="运行" Padding="15 0 15 0" Margin="5" Click="Run_Click" x:Name="RunningButton" /> |
| | | <Button Content="运行(Home)" Padding="15 0 15 0" Margin="5" Click="Run_Click" x:Name="RunningButton" /> |
| | | </StackPanel> |
| | | </Grid> |
| | | |
| | |
| | | using System.Windows.Controls; |
| | | using ZTImage.Configuration; |
| | | using ZTImage.Log; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Dnf; |
| | | using System.Windows.Interop; |
| | | using RichCreator.Maps.Kalete; |
| | | using ZTImage.Collections; |
| | | using System.Collections.Generic; |
| | | |
| | | namespace RichCreator |
| | | { |
| | |
| | | /// <param name="e"></param> |
| | | private void Run_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | Int32 taskIndex = this.taskName.SelectedIndex; |
| | | MapType mapType = (MapType)this.taskName.SelectedIndex; |
| | | if (mapType == MapType.TestSpeed) |
| | | { |
| | | //测速 |
| | | G.Instance.InfoWriter("开始测速"); |
| | | TestSpeed(); |
| | | return; |
| | | } |
| | | else if (mapType == MapType.TestSkill) |
| | | { |
| | | //测技能 |
| | | G.Instance.InfoWriter("开始测技能"); |
| | | TestSkill(); |
| | | return; |
| | | } |
| | | else if (mapType == MapType.ReadRolePosition) |
| | | { |
| | | //读取角色位置 |
| | | G.Instance.InfoWriter("开始测角色位置"); |
| | | ReadRolePosition(); |
| | | return; |
| | | } |
| | | else if (mapType == MapType.TestToNextDoor) |
| | | { |
| | | //测试进入下一关的门 |
| | | G.Instance.InfoWriter("开始测进门"); |
| | | TestToNextDoor(); |
| | | return; |
| | | } |
| | | |
| | | if (isRunning) |
| | | { |
| | | monitor.Stop(); |
| | |
| | | } |
| | | G.Instance.DebugWriter("硬件检测通过"); |
| | | |
| | | this.monitor = new JobMonitor(taskIndex); |
| | | this.monitor = new JobMonitor(mapType); |
| | | monitor.Start(); |
| | | |
| | | startTaskUI(); |
| | |
| | | hsvImage = hsvImage.GetSubRect(new System.Drawing.Rectangle(0, 0, 1280, 720)); |
| | | |
| | | return DnfCVHelper.FindRole(hsvImage, new ZTRectangle(0, 0, 1280, 720)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 测速 |
| | | /// </summary> |
| | | private void TestSpeed() |
| | | { |
| | | ZTRectangle gameRect = ZTRectangle.Empty; |
| | | WindowUtils.GetDnfRect(out gameRect); |
| | | Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1); |
| | | Task.Run(() => |
| | | { |
| | | WindowUtils.SetDnfToTop(); |
| | | Thread.Sleep(1000); |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | ZTPoint start = DnfCVHelper.FindRole(hsvImage, gameRect); |
| | | |
| | | |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, HIDCode.LeftArrow); |
| | | Thread.Sleep(30); |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | Thread.Sleep(30); |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, HIDCode.LeftArrow); |
| | | Thread.Sleep(800); |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | |
| | | //G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, HIDCode.DownArrow); |
| | | //Thread.Sleep(1000); |
| | | //G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | |
| | | |
| | | |
| | | //G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, HIDCode.LeftArrow); |
| | | //Thread.Sleep(1000); |
| | | //G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | |
| | | |
| | | image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | ZTPoint end = DnfCVHelper.FindRole(hsvImage, gameRect); |
| | | |
| | | |
| | | G.Instance.InfoWriter($"from:{start},to:{end},distanceX:{end.X - start.X},distanceY:{end.Y - start.Y}"); |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 测技能 |
| | | /// </summary> |
| | | private void TestSkill() |
| | | { |
| | | ZTRectangle gameRect = ZTRectangle.Empty; |
| | | WindowUtils.GetDnfRect(out gameRect); |
| | | Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1); |
| | | Task.Run(() => { |
| | | WindowUtils.SetDnfToTop(); |
| | | Thread.Sleep(10); |
| | | |
| | | KaleteMap map = new KaleteMap(gameRect, CancellationToken.None); |
| | | Int32 lastHouseIndex = -1; |
| | | Int32 houseIndex = -1; |
| | | |
| | | while (true) |
| | | { |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | if (map.MiniMap.GetCurrentHouseIndex(out houseIndex, image)) |
| | | { |
| | | if (houseIndex != lastHouseIndex) |
| | | { |
| | | G.Instance.InfoWriter($"entry house:{houseIndex}"); |
| | | lastHouseIndex = houseIndex; |
| | | //发技能 |
| | | map.EntryHousePrework(houseIndex, lastHouseIndex); |
| | | } |
| | | } |
| | | Thread.Sleep(500); |
| | | } |
| | | |
| | | G.Instance.InfoWriter($"测试技能发放完成"); |
| | | }); |
| | | } |
| | | |
| | | private ZTPoint rolePosition = ZTPoint.Empty; |
| | | |
| | | /// <summary> |
| | | /// 读取角色位置 |
| | | /// </summary> |
| | | private void ReadRolePosition() |
| | | { |
| | | ZTRectangle gameRect = ZTRectangle.Empty; |
| | | WindowUtils.GetDnfRect(out gameRect); |
| | | Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1); |
| | | Task.Run(() => { |
| | | WindowUtils.SetDnfToTop(); |
| | | Thread.Sleep(1000); |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | rolePosition = DnfCVHelper.FindRole(hsvImage, gameRect); |
| | | |
| | | |
| | | G.Instance.InfoWriter($"角色位置读取成功:{rolePosition}"); |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 测试进入下一关的门 |
| | | /// </summary> |
| | | private void TestToNextDoor() |
| | | { |
| | | HouseInfo house = new HouseInfo(0, MapType.Kalete, false, null); |
| | | |
| | | ZTRectangle gameRect = ZTRectangle.Empty; |
| | | WindowUtils.GetDnfRect(out gameRect); |
| | | Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X, gameRect.End.Y - gameRect.Start.Y ); |
| | | Task.Run(() => { |
| | | WindowUtils.SetDnfToTop(); |
| | | Thread.Sleep(10); |
| | | |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | image.ROI = new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X, gameRect.End.Y - gameRect.Start.Y); |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | image.ROI = System.Drawing.Rectangle.Empty; |
| | | |
| | | //定位点 |
| | | ParametersPoint locationCoor = DnfCVHelper.GetLocationPoint(image, gameRect); |
| | | if (locationCoor.Equals(ParametersPoint.Empty)) |
| | | { |
| | | //找不到定位点 |
| | | G.Instance.InfoWriter("找不到定位点"); |
| | | return; |
| | | } |
| | | |
| | | ZTPoint rolePosition = DnfCVHelper.FindRole(hsvImage, gameRect); |
| | | ZTPoint start=house.ScreenToMapCoordinate(rolePosition, locationCoor); |
| | | |
| | | |
| | | |
| | | DnfRole role = new DnfRole(gameRect); |
| | | |
| | | Int32 doorIndex = 0; |
| | | List<ZTPoint> paths=house.FindDoorPath(out doorIndex,start); |
| | | ZTPoint last = start; |
| | | for (int i = 0; i < paths.Count; i++) |
| | | { |
| | | //移动 |
| | | ZTPoint distance = paths[i].Sub(last); |
| | | last = paths[i]; |
| | | role.SyncMove(distance); |
| | | } |
| | | |
| | | |
| | | |
| | | G.Instance.InfoWriter($"测试进入下一关的门完成"); |
| | | }); |
| | | } |
| | | |
| | | |
| | |
| | | isRunning = false; |
| | | })); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | |
| | | |
| | | private int hotKeyID = 2839; |
| | | /// <summary> |
| | | /// 热键消息 |
| | | /// </summary> |
| | | const int WindowsMessageHotkey = 786; |
| | | |
| | | private void Window_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | //注册热键 |
| | | IntPtr intPtr = (new WindowInteropHelper(this)).Handle; |
| | | if (!SystemHotKey.RegHotKey(intPtr, hotKeyID, SystemHotKey.KeyModifiers.None, System.Windows.Forms.Keys.Home)) |
| | | { |
| | | MessageBox.Show("热键不可用,其它应用已经占用热键"); |
| | | } |
| | | else |
| | | { |
| | | ComponentDispatcher.ThreadPreprocessMessage += (ref MSG Message, ref bool Handled) => |
| | | { |
| | | // 判断是否热键消息 |
| | | if (Message.message == WindowsMessageHotkey) |
| | | { |
| | | // 获取热键id |
| | | var id = Message.wParam.ToInt32(); |
| | | // 执行热键回调方法(执行时需要判断是否与注册的热键匹配) |
| | | if (id == hotKeyID) |
| | | { |
| | | Run_Click(this, new RoutedEventArgs()); |
| | | } |
| | | |
| | | } |
| | | }; |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | private void Window_Unloaded(object sender, RoutedEventArgs e) |
| | | { |
| | | //注销热键 |
| | | IntPtr intPtr = (new WindowInteropHelper(this)).Handle; |
| | | SystemHotKey.UnRegHotKey(intPtr, hotKeyID); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Dnf; |
| | | using RichCreator.Jobs.StateMachines; |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.CV; |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.Utility.Utilitys; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Threading; |
| | | |
| | | namespace RichCreator.Maps.Kalete |
| | | { |
| | | /// <summary> |
| | | /// 卡勒特地图 |
| | | /// </summary> |
| | | public class KaleteMap : MapInfo |
| | | { |
| | | public KaleteMap(ZTRectangle gameRect, CancellationToken cancelToken) : base(MapType.Lingdong, gameRect, cancelToken) |
| | | { |
| | | this.MiniMap = new KaleteMiniMap(gameRect); |
| | | this.Role = new DnfRole(gameRect); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 地图的所有房间 |
| | | /// NextIndex=-1,完成 |
| | | /// NextIndex=-2,出错 |
| | | /// </summary> |
| | | private static readonly HouseInfo[] Houses = new HouseInfo[] { |
| | | new HouseInfo (0 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (1 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (2 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (3 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (4 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (5 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (6 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (7 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (8 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-148,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (9 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-300,DoorDirection=new[]{Direction.Left} }, |
| | | new HouseInfo (10,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (11,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (12,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-220,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (13,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-320,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (14,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-320,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (15,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (16,MapType.Lingdong,true ,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (17,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (18,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (19,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } } |
| | | }; |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 角色 |
| | | /// </summary> |
| | | public DnfRole Role { get; set; } |
| | | |
| | | |
| | | private Int32 runningStep = RunningStep.None; |
| | | |
| | | /// <summary> |
| | | /// 开始 |
| | | /// </summary> |
| | | /// <param name="gameRect"></param> |
| | | /// <param name="cancelToken"></param> |
| | | /// <param name="runningStep"></param> |
| | | /// <returns></returns> |
| | | public override ZTResult Start(Int32 runningStep) |
| | | { |
| | | this.runningStep = runningStep; |
| | | |
| | | |
| | | WindowUtils.SetDnfToTop(); |
| | | |
| | | |
| | | |
| | | if (runningStep < RunningStep.War) |
| | | { |
| | | if (!MoveToSunan()) |
| | | { |
| | | return ZTResult.Failed; |
| | | } |
| | | |
| | | if (!MoveToShikongzhimen()) |
| | | { |
| | | return ZTResult.Failed; |
| | | } |
| | | |
| | | if (!MoveToChoiceTaskPage()) |
| | | { |
| | | return ZTResult.Failed; |
| | | } |
| | | |
| | | if (!IntoHouse()) |
| | | { |
| | | return ZTResult.Failed; |
| | | } |
| | | |
| | | G.Instance.InfoWriter("成功进入副本"); |
| | | } |
| | | |
| | | while (true) |
| | | { |
| | | //重复刷,直到疲劳值不够了 |
| | | if (this.CancelToken.IsCancellationRequested) |
| | | { |
| | | return ZTResult.Cancel; |
| | | } |
| | | |
| | | |
| | | DateTime startHouse = DateTime.Now; |
| | | ZTResult killResult = KillMonster(); |
| | | if (killResult == ZTResult.Success) |
| | | { |
| | | //捡东西 |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.V); |
| | | Thread.Sleep(1000); |
| | | for (int i = 0; i < 5; i++) |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X); |
| | | Thread.Sleep(RandomUtils.KeyPressDuration * 3); |
| | | } |
| | | |
| | | |
| | | //卖装备并关闭商店 |
| | | SaleEquipment(); |
| | | |
| | | Int32 houseTotalSecond = (Int32)(DateTime.Now - startHouse).TotalSeconds; |
| | | G.Instance.InfoWriter("单次刷图成功,用时:" + (houseTotalSecond / 60) + "分" + (houseTotalSecond % 60) + "秒"); |
| | | |
| | | //查询疲劳值 |
| | | Int32 pilaozhi = DnfCVHelper.GetPiLaoZhi(this.GameRect); |
| | | |
| | | G.Instance.InfoWriter("疲劳值:" + pilaozhi); |
| | | if (pilaozhi <= 0) |
| | | { |
| | | ExitToTown(); |
| | | return ZTResult.Success; |
| | | } |
| | | |
| | | ReplayGame(); |
| | | continue; |
| | | } |
| | | else |
| | | { |
| | | return killResult; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否进入打怪地图 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public override bool IsEntryMap() |
| | | { |
| | | //查找顶端卡勒特之初文字 |
| | | bool findResult = FuncUtils.TimeoutCancelableWrap(2 * 60 * 1000, CancelToken, () => |
| | | { |
| | | using (Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage()) |
| | | { |
| | | return KaleteCVHelper.ExistKaleteText(image, this.GameRect); |
| | | } |
| | | }, 10); |
| | | |
| | | |
| | | return findResult; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 进入房间后的预先工作 |
| | | /// </summary> |
| | | /// <param name="houseIndex"></param> |
| | | /// <param name="preHouseIndex"></param> |
| | | public override void EntryHousePrework(int houseIndex, int preHouseIndex) |
| | | { |
| | | //移动和发招 |
| | | switch (houseIndex) |
| | | { |
| | | case 0: |
| | | this.Role.SyncMove(new ZTPoint(550, 0)); |
| | | this.Role.ReleaseSkill(HIDCode.R, 1000); |
| | | this.Role.ReleaseSkill(HIDCode.E, 1000); |
| | | break; |
| | | case 1: |
| | | this.Role.SyncMove(new ZTPoint(300, 0)); |
| | | this.Role.ReleaseSkill(HIDCode.Q, 1300); |
| | | this.Role.ReleaseSkill(HIDCode.W, 1000); |
| | | break; |
| | | case 6: |
| | | this.Role.SyncMove(new ZTPoint(448, 94)); |
| | | this.Role.ReleaseSkill(HIDCode.G, 0); |
| | | break; |
| | | case 7: |
| | | this.Role.SyncMove(new ZTPoint(530, 0)); |
| | | this.Role.ReleaseSkill(HIDCode.R, 0); |
| | | break; |
| | | case 8: |
| | | this.Role.SyncMove(new ZTPoint(453, 0)); |
| | | this.Role.ReleaseSkill(HIDCode.H, 0); |
| | | break; |
| | | case 13: |
| | | this.Role.SyncMove(new ZTPoint(-100, 203)); |
| | | this.Role.ReleaseSkill(HIDCode.Q, 1300); |
| | | this.Role.ReleaseSkill(HIDCode.E, 0); |
| | | break; |
| | | case 12: |
| | | this.Role.SyncMove(new ZTPoint(-851, 120)); |
| | | this.Role.ReleaseSkill(HIDCode.T, 0); |
| | | break; |
| | | case 17: |
| | | this.Role.SyncMove(new ZTPoint(-306, 130)); |
| | | this.Role.ReleaseSkill(HIDCode.Q, 1300); |
| | | this.Role.ReleaseSkill(HIDCode.F, 0);//用w代替 |
| | | break; |
| | | case 16: |
| | | this.Role.SyncMove(new ZTPoint(-385, 0)); |
| | | this.Role.ReleaseSkill(HIDCode.Y, 0); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// esc退到城镇 |
| | | /// </summary> |
| | | private void ExitToTown() |
| | | { |
| | | G.Instance.DebugWriter("返回城镇"); |
| | | Utility.Structs.ZTPoint point = new Utility.Structs.ZTPoint(this.GameRect.End.X - 124, this.GameRect.Start.Y + 146); |
| | | G.Instance.InputControl.MoveToAndClick(point); |
| | | Thread.Sleep(5000); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 点击再次挑战 |
| | | /// </summary> |
| | | private void ReplayGame() |
| | | { |
| | | G.Instance.DebugWriter("重新挑战"); |
| | | Utility.Structs.ZTPoint point = new Utility.Structs.ZTPoint(this.GameRect.End.X - 132, this.GameRect.Start.Y + 90); |
| | | G.Instance.InputControl.MoveToAndClick(point); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 刷房间 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private ZTResult KillMonster() |
| | | { |
| | | bool ret = false; |
| | | |
| | | if (!IsEntryMap()) |
| | | { |
| | | G.Instance.InfoWriter("未找到进入凛冬"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("进入凛冬"); |
| | | |
| | | Int32 preHouseIndex = -1; |
| | | Int32 houseIndex = -1; |
| | | |
| | | |
| | | //技能加成 |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Space); |
| | | |
| | | //循环刷房间 |
| | | while (true) |
| | | { |
| | | preHouseIndex = houseIndex; |
| | | //看房间号 |
| | | ret = this.MiniMap.GetCurrentHouseIndexWaitTimeout(out houseIndex, null, this.CancelToken, 3 * 1000); |
| | | if (!ret) |
| | | { |
| | | G.Instance.InfoWriter("未找到人物所在房间"); |
| | | return ZTResult.Failed; |
| | | } |
| | | |
| | | G.Instance.InfoWriter("进入房间->" + houseIndex.ToString()); |
| | | |
| | | HouseInfo houseInfo = Houses[houseIndex]; |
| | | this.Role.SetHouse(houseInfo); |
| | | DateTime startTime = DateTime.Now; |
| | | KillMonsterStateMachine kmsm = new KillMonsterStateMachine(this, houseInfo,this.Role, preHouseIndex, this.runningStep); |
| | | ZTResult smresult = kmsm.Work(5 * 60 * 1000); |
| | | Int32 roomTotalSecond = (Int32)(DateTime.Now - startTime).TotalSeconds; |
| | | G.Instance.InfoWriter("房间刷完,用时:" + (roomTotalSecond / 60) + "分" + (roomTotalSecond % 60) + "秒"); |
| | | |
| | | runningStep = RunningStep.None; |
| | | if (smresult == ZTResult.Success) |
| | | { |
| | | if (houseInfo.IsEnd) |
| | | { |
| | | //所有房间刷完 |
| | | return ZTResult.Success; |
| | | } |
| | | |
| | | //刷其它房间 |
| | | continue; |
| | | } |
| | | else |
| | | { |
| | | return smresult; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 步行到素喃 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool MoveToSunan() |
| | | { |
| | | bool result = FuncUtils.NoChangeRetryCallWrap( |
| | | () => |
| | | { |
| | | WindowUtils.SetDnfToTop(); |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | //向下走出赛丽亚的房间 ,走向素喃 |
| | | G.Instance.InputControl.PressKey(2000, HIDCode.DownArrow); |
| | | }, |
| | | () => |
| | | { |
| | | G.Instance.InfoWriter("检测是否进入素喃"); |
| | | result = FuncUtils.TimeoutCancelableWrap(10000, this.CancelToken, () => |
| | | { |
| | | return LindongCVHelper.IsInSunan(this.GameRect); |
| | | }); |
| | | if (!result) |
| | | { |
| | | G.Instance.InfoWriter("进入素喃失败"); |
| | | return false; |
| | | } |
| | | |
| | | G.Instance.InfoWriter("进入素喃成功"); |
| | | return true; |
| | | }, |
| | | () => |
| | | { |
| | | return DnfCVHelper.IsInSaiLiYaHouse(this.GameRect); |
| | | }); |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 步行至时空之门 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool MoveToShikongzhimen() |
| | | { |
| | | bool result = FuncUtils.NoChangeRetryCallWrap(() => |
| | | { |
| | | //打开地图 |
| | | ZTPoint mapButtonPosition = new ZTPoint(this.GameRect.End.X - 14, this.GameRect.Start.Y + 16); |
| | | G.Instance.InputControl.MoveToAndClick(mapButtonPosition); |
| | | Thread.Sleep(1000); |
| | | |
| | | //点到副本之前的地图 |
| | | ZTPoint mapPrePosition = new ZTPoint(this.GameRect.Start.X + 382, this.GameRect.Start.Y + 252); |
| | | G.Instance.InputControl.MoveToAndClick(mapPrePosition); |
| | | |
| | | //关闭地图框 |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | }, |
| | | () => |
| | | { |
| | | //检测是否进入时空之门 |
| | | return FuncUtils.TimeoutCancelableWrap(15000, this.CancelToken, () => |
| | | { |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | return LindongCVHelper.IsInShikongzhimen(this.GameRect); |
| | | }); |
| | | }, |
| | | () => |
| | | { |
| | | //检测是否还在素喃 |
| | | return FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => |
| | | { |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | return LindongCVHelper.IsInSunan(this.GameRect); |
| | | }); |
| | | }); |
| | | |
| | | Thread.Sleep(5000); |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 步行到任务选择和正式开打页面 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool MoveToChoiceTaskPage() |
| | | { |
| | | bool result = false; |
| | | //右走进选择副本界面 |
| | | G.Instance.InputControl.PressKey(1500, HIDCode.LeftArrow); |
| | | |
| | | |
| | | G.Instance.InfoWriter("检测是否打开选择副本界面"); |
| | | result = FuncUtils.TimeoutCancelableWrap(10000, this.CancelToken, () => |
| | | { |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | return LindongCVHelper.IsInChoiceTaskPage(image, this.GameRect); |
| | | }); |
| | | if (!result) |
| | | { |
| | | G.Instance.InfoWriter("进入打开选择副本界面失败"); |
| | | return false; |
| | | } |
| | | G.Instance.InfoWriter("打开选择副本界面成功"); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 进入指定房间 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool IntoHouse() |
| | | { |
| | | bool result = false; |
| | | //选择凛冬 |
| | | G.Instance.InfoWriter("开始选择卡勒特之初"); |
| | | |
| | | Int32 nandu = 0; |
| | | if (!SelectKalete(out nandu)) |
| | | { |
| | | G.Instance.InfoWriter("选择卡勒特之初失败"); |
| | | return false; |
| | | } |
| | | G.Instance.InfoWriter("选择卡勒特之初成功,难度:" + nandu); |
| | | |
| | | |
| | | |
| | | if (nandu != 4) |
| | | { |
| | | G.Instance.InfoWriter("开始选择难度"); |
| | | result = SelectNandu(nandu); |
| | | if (!result) |
| | | { |
| | | G.Instance.InfoWriter("选择难度失败"); |
| | | return false; |
| | | } |
| | | G.Instance.InfoWriter("选择难度成功"); |
| | | } |
| | | |
| | | |
| | | //开始 |
| | | G.Instance.InputControl.PressKey(80, HIDCode.Space); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 关闭所有弹出窗 |
| | | /// </summary> |
| | | /// <param name="cancelToken"></param> |
| | | /// <param name="gameRect"></param> |
| | | /// <returns></returns> |
| | | private void CloseAllAlertWindow(CancellationToken cancelToken, ZTRectangle gameRect) |
| | | { |
| | | while (!cancelToken.IsCancellationRequested) |
| | | { |
| | | //G.Instance.InputControl.MoveTo(gameRect.Start.X,gameRect.Start.Y, false, false, false); |
| | | //Thread.Sleep(10); |
| | | //截图 |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | |
| | | ZTRectangle closeButtonRect = ZTRectangle.Empty; |
| | | if (!DnfCVHelper.GetAlertWindow(out closeButtonRect, image, gameRect)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | G.Instance.InputControl.MoveToAndClick(closeButtonRect.GetCenterPoint()); |
| | | Thread.Sleep(500); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 选择凛冬 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool SelectKalete(out Int32 nandu) |
| | | { |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | |
| | | if (KaleteCVHelper.GetChoiceKaleteNandu(out nandu, image, this.GameRect)) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | G.Instance.InputControl.MoveToAndClick(new ZTPoint(this.GameRect.Start.X + 819, this.GameRect.Start.Y + 181)); |
| | | Thread.Sleep(5000); |
| | | image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | if (KaleteCVHelper.GetChoiceKaleteNandu(out nandu, image, this.GameRect)) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 选择难度 |
| | | /// </summary> |
| | | /// <param name="rightCan"></param> |
| | | /// <param name="leftCan"></param> |
| | | /// <returns></returns> |
| | | private bool SelectNandu(Int32 nandu) |
| | | { |
| | | Int32 count = 4 - nandu; |
| | | for (int i = 0; i < Math.Abs(count); i++) |
| | | { |
| | | if (count < 0) |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.LeftArrow); |
| | | } |
| | | else |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightArrow); |
| | | } |
| | | Thread.Sleep(400); |
| | | } |
| | | |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | if (!KaleteCVHelper.GetChoiceKaleteNandu(out nandu, image, this.GameRect)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (nandu == 4) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 出售装备 |
| | | /// </summary> |
| | | /// <param name="saleButtonRect"></param> |
| | | private bool SaleEquipment() |
| | | { |
| | | //卖装备并关闭商店 |
| | | ZTRectangle closeButtonRect = ZTRectangle.Empty; |
| | | ZTRectangle saleButtonRect = ZTRectangle.Empty; |
| | | if (!DnfCVHelper.HasSaleButton(out saleButtonRect, out closeButtonRect, this.GameRect)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | //卖装备 |
| | | G.Instance.InfoWriter("出售装备"); |
| | | G.Instance.InputControl.MoveToAndClick(saleButtonRect.GetCenterPoint()); |
| | | |
| | | //得到装备文字位置 |
| | | ZTRectangle equipmentTextRect = ZTRectangle.Empty; |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => |
| | | { |
| | | Int32 status = 0; |
| | | if (DnfCVHelper.GetEquipmentSelectStatus(out equipmentTextRect, out status, this.GameRect)) |
| | | { |
| | | if (status == 1) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | G.Instance.InputControl.MoveToAndClick(equipmentTextRect.GetCenterPoint()); |
| | | } |
| | | return false; |
| | | }); |
| | | |
| | | if (!result) |
| | | { |
| | | G.Instance.InfoWriter("装备文字未取到"); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | //开始点,每格步进30 |
| | | ZTPoint startPoint = new Utility.Structs.ZTPoint(equipmentTextRect.End.X - 30, equipmentTextRect.End.Y + 9); |
| | | List<Int32> points = DnfCVHelper.GetEquipmentIndexs(startPoint); |
| | | |
| | | for (int i = 0; i < points.Count; i++) |
| | | { |
| | | Int32 index = points[i]; |
| | | |
| | | int row = index / 8; |
| | | int col = index % 8; |
| | | int x = col * 30 + 15; |
| | | int y = row * 30 + 15; |
| | | |
| | | //点窗格 |
| | | G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint(startPoint.X + x, startPoint.Y + y)); |
| | | Thread.Sleep(500); |
| | | //点确定 |
| | | G.Instance.InputControl.Move(0, 0, true, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration); |
| | | G.Instance.InputControl.Move(0, 0, false, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration); |
| | | } |
| | | G.Instance.DebugWriter("equipment:" + ZTImage.Utils.ConcatString(points.ToArray(), ",")); |
| | | Thread.Sleep(RandomUtils.KeyPressDuration); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Escape); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Dnf; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.CV; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Maps.Kalete |
| | | { |
| | | public class KaleteMiniMap : IMiniMap |
| | | { |
| | | public KaleteMiniMap(ZTRectangle gameRect):base(gameRect, new ZTPoint(1183, 47)) |
| | | {} |
| | | |
| | | |
| | | |
| | | protected override bool GetCurrentHouse(out Int32 houseIndex, Image<Rgb, byte> image) |
| | | { |
| | | houseIndex = -1; |
| | | Int32 overHouseDected = -1; |
| | | for (int i = 0; i < 20; i++) |
| | | { |
| | | Int32 row = i / 5; |
| | | Int32 col = i % 5; |
| | | |
| | | //目标块第一块坐标 |
| | | Int32 x = this.MinimapOffset.X + col * 18; |
| | | Int32 y = this.MinimapOffset.Y + row * 18; |
| | | |
| | | if (DnfCVHelper.IsCurrentHouseColor(image,x,y)) |
| | | { |
| | | //当前房间 |
| | | houseIndex = i; |
| | | return true; |
| | | } |
| | | |
| | | if (i == 16) |
| | | { |
| | | //17格是否青色并且16格是红色,则认为角色在16房间 |
| | | if (DnfCVHelper.IsCrossedHouseColor(image, x+18, y)) |
| | | { |
| | | if (DnfCVHelper.IsOverHouseColor(image,x,y)) |
| | | { |
| | | overHouseDected = 16; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | if (overHouseDected > -1) |
| | | { |
| | | //其它房间没有,并且已经检测到了最后一个房间 |
| | | houseIndex = overHouseDected; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utilitys; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using RichCreator.Dnf; |
| | | |
| | | namespace RichCreator.Maps.Kalete |
| | | { |
| | | /// <summary> |
| | | /// 禁区类 |
| | | /// </summary> |
| | | public class OutOfBounds |
| | | { |
| | | public OutOfBounds(ZTRectangle gameRect,DnfRole moveState) |
| | | { |
| | | this.moveState = moveState; |
| | | this.gameRect = gameRect; |
| | | bounds = new ZTRectangle[] { |
| | | new ZTRectangle (1089+gameRect.Start.X,0+gameRect.Start.Y,1280+gameRect.End.X,394+gameRect.End.Y) |
| | | |
| | | }; |
| | | } |
| | | /// <summary> |
| | | /// 五号房间的右上角区域 |
| | | /// </summary> |
| | | public const Int32 AREA_5Bound = 0; |
| | | |
| | | /// <summary> |
| | | /// 14号房间那个不动的怪 |
| | | /// </summary> |
| | | public const Int32 AREA_14Bound = 1; |
| | | |
| | | |
| | | private ZTRectangle gameRect; |
| | | |
| | | private DnfRole moveState; |
| | | |
| | | private ZTRectangle[] bounds = null; |
| | | |
| | | /// <summary> |
| | | /// 判断是否在禁区内 |
| | | /// </summary> |
| | | /// <param name="houseIndex"></param> |
| | | /// <param name="rolePosition"></param> |
| | | /// <param name="areaID"></param> |
| | | /// <returns></returns> |
| | | public bool InOutOfBound(Int32 houseIndex, ZTPoint rolePosition,out int areaID) |
| | | { |
| | | areaID = 0; |
| | | switch (houseIndex) |
| | | { |
| | | case 5: |
| | | if (Utilitys.Utils.IsInRect(rolePosition, bounds[AREA_5Bound])) |
| | | { |
| | | areaID = AREA_5Bound; |
| | | return true; |
| | | } |
| | | return false; |
| | | case 14: |
| | | areaID = AREA_14Bound; |
| | | break; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移动到正常区域 |
| | | /// </summary> |
| | | /// <param name="areaID"></param> |
| | | /// <returns></returns> |
| | | public void MoveToCommonBound(Int32 areaID) |
| | | { |
| | | switch (areaID) |
| | | { |
| | | case AREA_5Bound: |
| | | this.moveState.SyncMove(new ZTPoint(-600, 0)); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Threading; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Skills; |
| | | using RichCreator.Dnf; |
| | | |
| | | namespace RichCreator.Maps |
| | | namespace RichCreator.Maps.Lindong |
| | | { |
| | | /// <summary> |
| | | /// 凛冬地图 |
| | | /// </summary> |
| | | public class LindongMap : MapInfo |
| | | { |
| | | public LindongMap(ZTRectangle gameRect, CancellationToken cancelToken) :base(MapType.Lingdong,gameRect,cancelToken) |
| | | { |
| | | this.MiniMap = new LindongMiniMap(gameRect); |
| | | this.Role = new DnfRole(gameRect); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 角色 |
| | | /// </summary> |
| | | public DnfRole Role { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 地图的所有房间 |
| | | /// NextIndex=-1,完成 |
| | | /// NextIndex=-2,出错 |
| | | /// </summary> |
| | | internal static HouseInfo[] Houses = new HouseInfo[] { |
| | | new HouseInfo (){ Index=0 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=1 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (){ Index=2 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=3 ,NextIndex=2 , OpenStatusDetectIndex=2 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=4 ,NextIndex=8 , OpenStatusDetectIndex=8 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (){ Index=5 ,NextIndex=4 , OpenStatusDetectIndex=4 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=6 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=7 ,NextIndex=6 , OpenStatusDetectIndex=6 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=8 ,NextIndex=12 ,OpenStatusDetectIndex=12, HouseCenterMoveLine=-148,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new HouseInfo (){ Index=9 ,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-300,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new HouseInfo (){ Index=10,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (){ Index=11,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=12,NextIndex=13, OpenStatusDetectIndex=12, HouseCenterMoveLine=-220,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=13,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=14,NextIndex=15, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=15,NextIndex=-1, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-250,IsEnd=true, DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=16,NextIndex=12, OpenStatusDetectIndex=12, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (){ Index=17,NextIndex=13, OpenStatusDetectIndex=13, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (){ Index=18,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (){ Index=19,NextIndex=15, OpenStatusDetectIndex=15, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } } |
| | | private static readonly HouseInfo[] Houses = new HouseInfo[] { |
| | | new HouseInfo (0 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (1 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (2 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (3 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (4 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (5 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (6 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (7 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (8 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-148,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new HouseInfo (9 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-300,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new HouseInfo (10,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (11,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (12,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-220,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (13,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-320,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (14,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-320,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (15,MapType.Lingdong,true ,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (16,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (17,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (18,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (19,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } } |
| | | }; |
| | | |
| | | static LindongMap() |
| | | { |
| | | //1 |
| | | SkillQueue queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.G); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[2].Skills = queue; |
| | | |
| | | //2 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.W); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[1].Skills = queue; |
| | | |
| | | //3 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.Q); |
| | | //queue.EnQueue(false, HIDCode.T); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[5].Skills = queue; |
| | | |
| | | //4 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[4].Skills = queue; |
| | | |
| | | //5 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.W); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[8].Skills = queue; |
| | | |
| | | //6 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.R); |
| | | //queue.EnQueue(false, HIDCode.T); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[9].Skills = queue; |
| | | |
| | | //7 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.Q); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[10].Skills = queue; |
| | | |
| | | |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.R); |
| | | //queue.EnQueue(false, HIDCode.T); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[12].Skills = queue; |
| | | |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.Q); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[13].Skills = queue; |
| | | |
| | | //8 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.W); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[14].Skills = queue; |
| | | |
| | | //9 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.H); |
| | | //queue.EnQueue(false, HIDCode.Y); |
| | | //queue.EnQueue(false, HIDCode.T); |
| | | //queue.EnQueue(false, HIDCode.R); |
| | | //queue.EnQueue(false, HIDCode.F); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[15].Skills = queue; |
| | | |
| | | |
| | | //10 |
| | | queue = new SkillQueue(); |
| | | //queue.EnQueue(false, HIDCode.W); |
| | | //queue.EnQueue(false, HIDCode.E); |
| | | queue.EnQueue(false, HIDCode.A); |
| | | queue.EnQueue(false, HIDCode.D); |
| | | queue.EnQueue(false, HIDCode.X); |
| | | Houses[18].Skills = queue; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 游戏区域 |
| | | /// </summary> |
| | | public ZTRectangle GameRect { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 小地图区域 |
| | | /// </summary> |
| | | public Utility.Structs.ZTPoint MinimapPoint = Utility.Structs.ZTPoint.Empty; |
| | | |
| | | //小地图距游戏区域的偏移 |
| | | private Utility.Structs.ZTPoint minimapPointOffset = new Utility.Structs.ZTPoint(1201, 47); |
| | | |
| | | public CancellationToken cancellationToken { get; set; } |
| | | |
| | | |
| | | private Int32 runningStep = RunningStep.None; |
| | | |
| | | public override ZTResult Start(ZTRectangle gameRect, CancellationToken cancelToken,Int32 runningStep) |
| | | |
| | | /// <summary> |
| | | /// 开始 |
| | | /// </summary> |
| | | /// <param name="gameRect"></param> |
| | | /// <param name="cancelToken"></param> |
| | | /// <param name="runningStep"></param> |
| | | /// <returns></returns> |
| | | public override ZTResult Start(Int32 runningStep) |
| | | { |
| | | this.runningStep = runningStep; |
| | | this.GameRect = gameRect; |
| | | this.cancellationToken = cancelToken; |
| | | this.MinimapPoint = gameRect.Start.Add(minimapPointOffset); |
| | | |
| | | |
| | | WindowUtils.SetDnfToTop(); |
| | | |
| | |
| | | while (true) |
| | | { |
| | | //重复刷,直到疲劳值不够了 |
| | | if (this.cancellationToken.IsCancellationRequested) |
| | | if (this.CancelToken.IsCancellationRequested) |
| | | { |
| | | return ZTResult.Cancel; |
| | | } |
| | |
| | | |
| | | |
| | | //卖装备并关闭商店 |
| | | SaleEquipment( this.cancellationToken); |
| | | SaleEquipment(); |
| | | |
| | | Int32 houseTotalSecond = (Int32)(DateTime.Now - startHouse).TotalSeconds; |
| | | //查询疲劳值 |
| | | G.Instance.InfoWriter("单次刷图成功,用时:"+(houseTotalSecond/60)+"分"+(houseTotalSecond%60)+"秒"); |
| | | |
| | | //查询疲劳值 |
| | | Int32 pilaozhi =DnfCVHelper.GetPiLaoZhi(this.GameRect); |
| | | |
| | | G.Instance.InfoWriter("疲劳值:" + pilaozhi); |
| | |
| | | return killResult; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否进入打怪地图 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public override bool IsEntryMap() |
| | | { |
| | | //查找顶端凛冬文字 |
| | | bool findResult = FuncUtils.TimeoutCancelableWrap(2 * 60 * 1000, CancelToken, () => { |
| | | using (Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage()) |
| | | { |
| | | return LindongCVHelper.ExistLingdongText(image, this.GameRect); |
| | | } |
| | | }, 10); |
| | | |
| | | //if (!findResult) |
| | | //{ |
| | | // G.Instance.InfoWriter("未找到进入凛冬的文字"); |
| | | //} |
| | | //else |
| | | //{ |
| | | // G.Instance.InfoWriter("进入凛冬"); |
| | | //} |
| | | |
| | | return findResult; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | G.Instance.InputControl.MoveToAndClick(point); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 刷房间 |
| | | /// </summary> |
| | |
| | | private ZTResult KillMonster() |
| | | { |
| | | bool ret = false; |
| | | |
| | | |
| | | //查找顶端凛冬文字 |
| | | bool findResult = FuncUtils.TimeoutCancelableWrap(2 * 60 * 1000, cancellationToken, () => { |
| | | using (Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage()) |
| | | { |
| | | return LindongCVHelper.ExistLingdongText(image, this.GameRect); |
| | | } |
| | | }, 10); |
| | | if (!findResult) |
| | | |
| | | if (!IsEntryMap()) |
| | | { |
| | | G.Instance.InfoWriter("未找到进入凛冬的文字"); |
| | | G.Instance.InfoWriter("未找到进入凛冬"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("进入凛冬"); |
| | | |
| | | |
| | | |
| | | Int32 preHouseIndex = -1; |
| | | Int32 houseIndex = -1; |
| | |
| | | { |
| | | preHouseIndex = houseIndex; |
| | | //看房间号 |
| | | ret=FuncUtils.TimeoutCancelableWrap(3 * 1000, this.cancellationToken, () => { |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.MinimapPoint); |
| | | }, 1); |
| | | ret = this.MiniMap.GetCurrentHouseIndexWaitTimeout(out houseIndex, null, this.CancelToken, 3 * 1000); |
| | | if (!ret) |
| | | { |
| | | G.Instance.InfoWriter("未找到人物所在房间"); |
| | |
| | | } |
| | | |
| | | G.Instance.InfoWriter("进入房间->" + houseIndex.ToString()); |
| | | |
| | | |
| | | DateTime roomStartTime = DateTime.Now; |
| | | KillMonsterStateMachine kmsm = new KillMonsterStateMachine(Houses[houseIndex], this.MinimapPoint, this.GameRect, preHouseIndex,this.runningStep, cancellationToken); |
| | | HouseInfo houseInfo = Houses[houseIndex]; |
| | | this.Role.SetHouse(houseInfo); |
| | | DateTime startTime = DateTime.Now; |
| | | KillMonsterStateMachine kmsm = new KillMonsterStateMachine(this, houseInfo,this.Role, preHouseIndex,this.runningStep); |
| | | ZTResult smresult = kmsm.Work( 5 * 60 * 1000); |
| | | Int32 roomTotalSecond = (Int32)(DateTime.Now - roomStartTime).TotalSeconds; |
| | | Int32 roomTotalSecond = (Int32)(DateTime.Now - startTime).TotalSeconds; |
| | | G.Instance.InfoWriter("房间刷完,用时:" + (roomTotalSecond / 60) + "分" + (roomTotalSecond % 60) + "秒"); |
| | | |
| | | runningStep = RunningStep.None; |
| | | if (smresult == ZTResult.Success) |
| | | { |
| | | if (houseIndex == 15) |
| | | if (houseInfo.IsEnd) |
| | | { |
| | | //所有房间刷完 |
| | | return ZTResult.Success; |
| | |
| | | () => |
| | | { |
| | | WindowUtils.SetDnfToTop(); |
| | | CloseAllAlertWindow(this.cancellationToken, this.GameRect); |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | //向下走出赛丽亚的房间 ,走向素喃 |
| | | G.Instance.InputControl.PressKey(2000, HIDCode.DownArrow); |
| | | }, |
| | | () => |
| | | { |
| | | G.Instance.InfoWriter("检测是否进入素喃"); |
| | | result = FuncUtils.TimeoutCancelableWrap(10000, this.cancellationToken, () => { |
| | | result = FuncUtils.TimeoutCancelableWrap(10000, this.CancelToken, () => { |
| | | return LindongCVHelper.IsInSunan(this.GameRect); |
| | | }); |
| | | if (!result) |
| | |
| | | G.Instance.InputControl.MoveToAndClick(mapPrePosition); |
| | | |
| | | //关闭地图框 |
| | | CloseAllAlertWindow(this.cancellationToken, this.GameRect); |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | }, |
| | | () => |
| | | { |
| | | //检测是否进入时空之门 |
| | | return FuncUtils.TimeoutCancelableWrap(15000, this.cancellationToken, () => |
| | | return FuncUtils.TimeoutCancelableWrap(15000, this.CancelToken, () => |
| | | { |
| | | CloseAllAlertWindow(this.cancellationToken, this.GameRect); |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | return LindongCVHelper.IsInShikongzhimen(this.GameRect); |
| | | }); |
| | | }, |
| | | () => |
| | | { |
| | | //检测是否还在素喃 |
| | | return FuncUtils.TimeoutCancelableWrap(3000, this.cancellationToken, () => { |
| | | CloseAllAlertWindow(this.cancellationToken, this.GameRect); |
| | | return FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | return LindongCVHelper.IsInSunan(this.GameRect); |
| | | }); |
| | | }); |
| | |
| | | |
| | | |
| | | G.Instance.InfoWriter("检测是否打开选择副本界面"); |
| | | result = FuncUtils.TimeoutCancelableWrap(10000, this.cancellationToken, () => { |
| | | result = FuncUtils.TimeoutCancelableWrap(10000, this.CancelToken, () => { |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | return LindongCVHelper.IsInChoiceTaskPage(image, this.GameRect); |
| | | }); |
| | |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 选择难度 |
| | | /// </summary> |
| | |
| | | /// 出售装备 |
| | | /// </summary> |
| | | /// <param name="saleButtonRect"></param> |
| | | private bool SaleEquipment(CancellationToken cancelToken) |
| | | private bool SaleEquipment() |
| | | { |
| | | //卖装备并关闭商店 |
| | | ZTRectangle closeButtonRect = ZTRectangle.Empty; |
| | |
| | | |
| | | //得到装备文字位置 |
| | | ZTRectangle equipmentTextRect = ZTRectangle.Empty; |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, cancelToken, () => { |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => { |
| | | Int32 status = 0; |
| | | if (DnfCVHelper.GetEquipmentSelectStatus(out equipmentTextRect, out status, this.GameRect)) |
| | | { |
| | |
| | | |
| | | |
| | | //开始点,每格步进30 |
| | | Utility.Structs.ZTPoint startPoint = new Utility.Structs.ZTPoint( equipmentTextRect.End.X-30, equipmentTextRect.End.Y+9); |
| | | ZTPoint startPoint = new Utility.Structs.ZTPoint( equipmentTextRect.End.X-30, equipmentTextRect.End.Y+9); |
| | | List<Int32> points = DnfCVHelper.GetEquipmentIndexs(startPoint); |
| | | |
| | | for (int i = 0; i < points.Count; i++) |
| | |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Escape); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | public override void EntryHousePrework(int houseIndex, int preHouseIndex) |
| | | { |
| | | //移动和发招 |
| | | switch (houseIndex) |
| | | { |
| | | case 2: |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.LeftArrow); |
| | | this.Role.SyncMove(new ZTPoint(-110, 0)); |
| | | G.Instance.InputControl.PressKeys(HIDCode.LeftArrow, HIDCode.G); |
| | | |
| | | break; |
| | | case 1: |
| | | this.Role.SyncMove(new ZTPoint(-480, 80)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.W); |
| | | break; |
| | | case 5: |
| | | //G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightArrow); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.R); |
| | | Thread.Sleep(1000); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.T); |
| | | break; |
| | | case 4: |
| | | this.Role.SyncMove(new ZTPoint(-1150, -50)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightArrow); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.E); |
| | | //Thread.Sleep(1000); |
| | | //G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.E); |
| | | break; |
| | | case 8: |
| | | this.Role.SyncMove(new ZTPoint(-100, 110)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightArrow); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.G); |
| | | //Thread.Sleep(300); |
| | | //G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Z); |
| | | break; |
| | | case 9: |
| | | this.Role.SyncMove(new ZTPoint(325, 65)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.R); |
| | | Thread.Sleep(1000); |
| | | this.Role.SyncMove(new ZTPoint(300, 0)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.T); |
| | | break; |
| | | case 10: |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Q); |
| | | break; |
| | | case 12: |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightArrow); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.R); |
| | | Thread.Sleep(1000); |
| | | this.Role.SyncMove(new ZTPoint(-110, 0)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.T); |
| | | break; |
| | | case 13: |
| | | if (preHouseIndex == 12) |
| | | { |
| | | this.Role.SyncMove(new ZTPoint(600, 150)); |
| | | } |
| | | else |
| | | { |
| | | this.Role.SyncMove(new ZTPoint(-300, 200)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightArrow); |
| | | } |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Q); |
| | | Thread.Sleep(1000); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.E); |
| | | break; |
| | | case 14: |
| | | if (preHouseIndex == 13) |
| | | { |
| | | this.Role.SyncMove(new ZTPoint(400, 0)); |
| | | } |
| | | else |
| | | { |
| | | this.Role.SyncMove(new ZTPoint(0, 100)); |
| | | } |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.W); |
| | | break; |
| | | |
| | | case 15: |
| | | this.Role.SyncMove(new ZTPoint(600, 0)); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.H); |
| | | Thread.Sleep(5000); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Y); |
| | | break; |
| | | case 18: |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.W); |
| | | break; |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Dnf; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.CV; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Maps.Lindong |
| | | { |
| | | public class LindongMiniMap : IMiniMap |
| | | { |
| | | public LindongMiniMap(ZTRectangle gameRect):base(gameRect, new ZTPoint(1201, 47)) |
| | | {} |
| | | |
| | | |
| | | |
| | | protected override bool GetCurrentHouse(out Int32 houseIndex, Image<Rgb, byte> image) |
| | | { |
| | | houseIndex = -1; |
| | | Int32 overHouseDected = -1; |
| | | for (int i = 0; i < 20; i++) |
| | | { |
| | | Int32 row = i / 4; |
| | | Int32 col = i % 4; |
| | | |
| | | //目标块第一块坐标 |
| | | Int32 x = this.MinimapOffset.X + col * 18; |
| | | Int32 y = this.MinimapOffset.Y + row * 18; |
| | | |
| | | if (DnfCVHelper.IsCurrentHouseColor(image, x, y)) |
| | | { |
| | | houseIndex = i; |
| | | return true; |
| | | } |
| | | |
| | | if (i == 15) |
| | | { |
| | | //查看,14格是否青色 |
| | | if (DnfCVHelper.IsCrossedHouseColor(image, x - 18, y)) |
| | | { |
| | | //是否怪物图像 |
| | | if ( DnfCVHelper.IsOverHouseColor(image,x,y)) |
| | | { |
| | | overHouseDected = 15; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (overHouseDected > -1) |
| | | { |
| | | houseIndex = overHouseDected; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using RichCreator.Dnf; |
| | | |
| | | namespace RichCreator.Maps.Lindong |
| | | { |
| | |
| | | /// </summary> |
| | | public class OutOfBounds |
| | | { |
| | | public OutOfBounds(ZTRectangle gameRect,MoveState moveState) |
| | | public OutOfBounds(ZTRectangle gameRect,DnfRole moveState) |
| | | { |
| | | this.moveState = moveState; |
| | | this.gameRect = gameRect; |
| | |
| | | |
| | | private ZTRectangle gameRect; |
| | | |
| | | private MoveState moveState; |
| | | private DnfRole moveState; |
| | | |
| | | private ZTRectangle[] bounds = null; |
| | | |
| New file |
| | |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.CV; |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.Utility.Utilitys; |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Jobs; |
| | | using RichCreator.Jobs.StateMachines; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Threading; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Dnf; |
| | | |
| | | namespace RichCreator.Maps.SkillSetting |
| | | { |
| | | /// <summary> |
| | | /// 技能设置地图 |
| | | /// </summary> |
| | | public class SkillSettingMap : MapInfo |
| | | { |
| | | public SkillSettingMap(ZTRectangle gameRect, CancellationToken cancelToken) : base(MapType.SkillSetting, gameRect, cancelToken) |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 标题文字 |
| | | /// </summary> |
| | | private ZTRectangle titleRect = ZTRectangle.Empty; |
| | | /// <summary> |
| | | /// lv字样 |
| | | /// </summary> |
| | | private ZTRectangle lvRect = ZTRectangle.Empty; |
| | | /// <summary> |
| | | /// 向上滚动按钮 |
| | | /// </summary> |
| | | private ZTRectangle upKeyRect = ZTRectangle.Empty; |
| | | |
| | | /// <summary> |
| | | /// 向下滚动按钮 |
| | | /// </summary> |
| | | private ZTRectangle downKeyRect = ZTRectangle.Empty; |
| | | |
| | | |
| | | |
| | | public override ZTResult Start(Int32 runningStep) |
| | | { |
| | | WindowUtils.SetDnfToTop(); |
| | | |
| | | |
| | | |
| | | if (!OpenSkillWindow()) |
| | | { |
| | | G.Instance.InfoWriter("打开技能窗口失败"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("技能窗口已打开"); |
| | | |
| | | //初始化 |
| | | if (!InitSkills()) |
| | | { |
| | | G.Instance.InfoWriter("初始化技能失败"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("技能已初始化"); |
| | | |
| | | |
| | | //点顶端的技能 |
| | | if (!SettingTopSkills()) |
| | | { |
| | | G.Instance.InfoWriter("通用技能设置失败"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("通用技能已设置"); |
| | | |
| | | //点sp技能 |
| | | if (!SettingSPSkills()) |
| | | { |
| | | G.Instance.InfoWriter("SP技能设置失败"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("SP技能已设置"); |
| | | |
| | | //点tp技能 |
| | | if (!SettingTPSkills()) |
| | | { |
| | | G.Instance.InfoWriter("TP技能设置失败"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("TP技能已设置"); |
| | | |
| | | //点学习 |
| | | if (!Studay()) |
| | | { |
| | | G.Instance.InfoWriter("技能学习失败"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("技能已学习"); |
| | | |
| | | //技能摆放 |
| | | if (!FormatSkillColumn()) |
| | | { |
| | | G.Instance.InfoWriter("技能摆放失败"); |
| | | return ZTResult.Failed; |
| | | } |
| | | G.Instance.InfoWriter("技能摆放成功"); |
| | | |
| | | |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | return ZTResult.Success; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 打开技能窗 |
| | | /// </summary> |
| | | /// <param name="titleRect"></param> |
| | | /// <param name="lvRect"></param> |
| | | /// <param name="upKeyRect"></param> |
| | | /// <param name="downKeyRect"></param> |
| | | /// <returns></returns> |
| | | private bool OpenSkillWindow() |
| | | { |
| | | bool isGray = false; |
| | | ZTRectangle innertitleRect=ZTRectangle.Empty, innerlvRect = ZTRectangle.Empty, innerupKeyRect = ZTRectangle.Empty, innerdownKeyRect = ZTRectangle.Empty; |
| | | for (int i = 0; i < 2; i++) |
| | | { |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration,HIDCode.K); |
| | | |
| | | bool result=FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => { |
| | | //识别技能窗 |
| | | return SkillCVHelper.FindSkillWindow(out innertitleRect, out innerlvRect, out innerupKeyRect, out innerdownKeyRect,out isGray, this.GameRect); |
| | | }); |
| | | |
| | | if (result) |
| | | { |
| | | titleRect = innertitleRect; |
| | | lvRect = innerlvRect; |
| | | upKeyRect = innerupKeyRect; |
| | | downKeyRect = innerdownKeyRect; |
| | | if (isGray) |
| | | { |
| | | //如果当前选的是tp技能学习(tp技能学习的右侧滚动条跟sp右侧的不一样),则: |
| | | //选中sp技能学习 |
| | | Utility.Structs.ZTPoint spPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 55, lvRect.Start.Y - 80); |
| | | G.Instance.InputControl.MoveToAndClick(spPoint); |
| | | |
| | | result = FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { |
| | | //识别技能窗 |
| | | return SkillCVHelper.FindCommonUpDownKey(out innerupKeyRect, out innerdownKeyRect, this.titleRect,this.GameRect); |
| | | },300); |
| | | if (!result) |
| | | { |
| | | continue; |
| | | } |
| | | upKeyRect = innerupKeyRect; |
| | | downKeyRect = innerdownKeyRect; |
| | | } |
| | | return true; |
| | | } |
| | | } |
| | | G.Instance.InfoWriter("打开技能对话框失败"); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | private bool InitSkills() |
| | | { |
| | | //点击初始化 |
| | | Utility.Structs.ZTPoint initButton = new Utility.Structs.ZTPoint(this.upKeyRect.Start.X - 37, this.upKeyRect.Start.Y - 86); |
| | | G.Instance.InputControl.MoveToAndClick(initButton); |
| | | |
| | | //是否已打开确认对话框 |
| | | ZTRectangle notificationRect = ZTRectangle.Empty; |
| | | bool result = FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { |
| | | return SkillCVHelper.ExistsNotificationText(out notificationRect,this.GameRect); |
| | | }); |
| | | if (!result) |
| | | { |
| | | G.Instance.DebugWriter("公告未找到"); |
| | | return false; |
| | | } |
| | | |
| | | //点击确认 |
| | | G.Instance.InputControl.Move(0, 0, true, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration); |
| | | G.Instance.InputControl.Move(0, 0, false, false, false); |
| | | Thread.Sleep(1000); |
| | | |
| | | |
| | | //是否已打开完毕对话框 |
| | | result = FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { |
| | | return SkillCVHelper.ExistsNotificationText(out notificationRect, this.GameRect); |
| | | }); |
| | | if (!result) |
| | | { |
| | | G.Instance.DebugWriter("完毕公告未找到"); |
| | | return false; |
| | | } |
| | | //点击确认 |
| | | Utility.Structs.ZTPoint okPosition = new Utility.Structs.ZTPoint(notificationRect.GetCenterPoint().X, notificationRect.End.Y + 60); |
| | | G.Instance.InputControl.MoveToAndClick(okPosition); |
| | | Thread.Sleep(RandomUtils.G(500,800)); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 关闭所有弹出窗 |
| | | /// </summary> |
| | | /// <param name="cancelToken"></param> |
| | | /// <param name="gameRect"></param> |
| | | /// <returns></returns> |
| | | private void CloseAllAlertWindow(CancellationToken cancelToken, ZTRectangle gameRect) |
| | | { |
| | | while (!cancelToken.IsCancellationRequested) |
| | | { |
| | | //G.Instance.InputControl.MoveTo(gameRect.Start.X,gameRect.Start.Y, false, false, false); |
| | | //Thread.Sleep(10); |
| | | //截图 |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | |
| | | ZTRectangle closeButtonRect = ZTRectangle.Empty; |
| | | if (!DnfCVHelper.GetAlertWindow(out closeButtonRect, image, gameRect)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | G.Instance.InputControl.MoveToAndClick(closeButtonRect.GetCenterPoint()); |
| | | Thread.Sleep(500); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置顶端技能 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool SettingTopSkills() |
| | | { |
| | | //物理暴击 |
| | | Utility.Structs.ZTPoint skillPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 200, lvRect.Start.Y - 42); |
| | | SettingSkill(skillPoint); |
| | | |
| | | //物理背击 |
| | | skillPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 280, lvRect.Start.Y - 42); |
| | | SettingSkill(skillPoint); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 要点的技能列表 |
| | | /// 内部为每个节所相对于节的相对位置 |
| | | /// </summary> |
| | | private List<Utility.Structs.ZTPoint>[] toAddLevelSkills = new List<Utility.Structs.ZTPoint>[] { |
| | | new List<Utility.Structs.ZTPoint> (){ |
| | | new Utility.Structs.ZTPoint(762-346,450-237),//疾风之棍棒精通 |
| | | }, |
| | | new List<Utility.Structs.ZTPoint> (){ |
| | | new Utility.Structs.ZTPoint(182,17),//朔风牵引 |
| | | new Utility.Structs.ZTPoint(274,17),//流风决 |
| | | new Utility.Structs.ZTPoint(481-251,342-262),//风鸣冲击 |
| | | new Utility.Structs.ZTPoint(323,82),//游离之风 |
| | | new Utility.Structs.ZTPoint(574-251,409-262),//双翼风刃 |
| | | new Utility.Structs.ZTPoint(574-251,477-262),//风暴之眼 |
| | | new Utility.Structs.ZTPoint(529-251,544-262),//真空旋风破 |
| | | }, |
| | | new List<Utility.Structs.ZTPoint> (){ |
| | | new Utility.Structs.ZTPoint(432-251,275-329),//风暴之拳 |
| | | new Utility.Structs.ZTPoint(479-251,342-329),//万象风龙阵 |
| | | new Utility.Structs.ZTPoint(572-251,340-329),//御风之力 |
| | | new Utility.Structs.ZTPoint(433-251,478-329),//风神决 |
| | | new Utility.Structs.ZTPoint(526-251,475-329),//风卷残云 |
| | | new Utility.Structs.ZTPoint(574-251,476-329),//游龙惊风破 |
| | | new Utility.Structs.ZTPoint(431-251,542-329),//九霄风雷 |
| | | new Utility.Structs.ZTPoint(663-295,545-331),//无限风域 |
| | | } |
| | | }; |
| | | |
| | | /// <summary> |
| | | /// 设置SP技能 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool SettingSPSkills() |
| | | { |
| | | //选中sp技能学习 |
| | | Utility.Structs.ZTPoint spPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 55, lvRect.Start.Y - 80); |
| | | G.Instance.InputControl.MoveToAndClick(spPoint); |
| | | |
| | | ZTRectangle numberLimitArea = new ZTRectangle(lvRect.Start.X-5,lvRect.End.Y,lvRect.End.X+21,lvRect.End.Y+340); |
| | | bool[] addedFlag = new bool[] {false,false,false }; |
| | | bool isdown = true; |
| | | for (int i = 0; i < 4; i++) |
| | | { |
| | | for (int count = 0; count < 10; count++) |
| | | { |
| | | if (this.CancelToken.IsCancellationRequested) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | //是否有数字 |
| | | bool result = FuncUtils.TimeoutCancelableWrap(1000, this.CancelToken, () => { |
| | | return SkillCVHelper.HasNumberText(numberLimitArea); |
| | | }, 100); |
| | | if (!result) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | //查找是否是某节, |
| | | Int32 numberSection = 0; |
| | | ZTRectangle sectionRect = ZTRectangle.Empty; |
| | | if (SkillCVHelper.IsNumberSections(out numberSection, out sectionRect, numberLimitArea)) |
| | | { |
| | | if (!addedFlag[numberSection]) |
| | | { |
| | | //没有添加,则循环把此节下的所有技能都加上 |
| | | foreach (var item in toAddLevelSkills[numberSection]) |
| | | { |
| | | SettingSkill(sectionRect.Start.Add(item)); |
| | | } |
| | | addedFlag[numberSection] = true; |
| | | } |
| | | |
| | | if (count == 0) |
| | | { |
| | | if (numberSection == 0) |
| | | { |
| | | //一开始是1区则向下 |
| | | isdown = true; |
| | | } |
| | | if (numberSection == 2) |
| | | { |
| | | //一开始是3区则向上 |
| | | isdown = false; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | if (isdown) |
| | | { |
| | | G.Instance.InputControl.MoveToAndClick(downKeyRect.GetCenterPoint()); |
| | | } |
| | | else |
| | | { |
| | | G.Instance.InputControl.MoveToAndClick(upKeyRect.GetCenterPoint()); |
| | | } |
| | | } |
| | | |
| | | if (addedFlag[0] == true && addedFlag[1] == true && addedFlag[2] == true) |
| | | { |
| | | return true; |
| | | } |
| | | isdown = !isdown; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置TP技能 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool SettingTPSkills() |
| | | { |
| | | //选中tp技能学习 |
| | | Utility.Structs.ZTPoint spPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 253, lvRect.Start.Y - 80); |
| | | G.Instance.InputControl.MoveToAndClick(spPoint); |
| | | |
| | | Utility.Structs.ZTPoint[] skills = new Utility.Structs.ZTPoint[] { |
| | | |
| | | new Utility.Structs.ZTPoint(334-296,277-251),//1.第一行第一个 |
| | | new Utility.Structs.ZTPoint(381-296,545-251),//2.第三行第二个 |
| | | new Utility.Structs.ZTPoint(664-296,413-251),//3.第二行倒数第三个 |
| | | new Utility.Structs.ZTPoint(567-296,410-251),//4.第二行倒数第五个 |
| | | new Utility.Structs.ZTPoint(758-296,411-251),//5.第二行倒数第一个 |
| | | }; |
| | | |
| | | for (int i = 0; i < skills.Length; i++) |
| | | { |
| | | SettingSkill(lvRect.Start.Add(skills[i])); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 学习 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool Studay() |
| | | { |
| | | Utility.Structs.ZTPoint studayPoint = new Utility.Structs.ZTPoint(this.downKeyRect.Start.X-331,this.downKeyRect.End.Y+27); |
| | | G.Instance.InputControl.MoveToAndClick(studayPoint); |
| | | Thread.Sleep(1000); |
| | | //点击确认 |
| | | G.Instance.InputControl.Move(0, 0, true, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration); |
| | | G.Instance.InputControl.Move(0, 0, false, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration*3); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置技能 |
| | | /// </summary> |
| | | /// <param name="skillPoint"></param> |
| | | /// <returns></returns> |
| | | private bool SettingSkill(Utility.Structs.ZTPoint skillPoint) |
| | | { |
| | | //84,71 |
| | | ZTRectangle limitRect = new ZTRectangle(skillPoint.X-84,skillPoint.Y-71,skillPoint.X+84,skillPoint.Y+71); |
| | | |
| | | bool result = false; |
| | | ZTRectangle addSkillLevelButton = ZTRectangle.Empty; |
| | | |
| | | //选中技能,试两次 |
| | | int addTry = 0; |
| | | for (; addTry < 2; addTry++) |
| | | { |
| | | bool skillIsFull = false; |
| | | G.Instance.InputControl.MoveToAndClick(skillPoint); |
| | | Thread.Sleep(500); |
| | | result = FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { |
| | | return SkillCVHelper.IsSelectSkill(out addSkillLevelButton, out skillIsFull, limitRect); |
| | | }); |
| | | if (result) |
| | | { |
| | | if (skillIsFull) |
| | | { |
| | | return true; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | if (addTry >= 2) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | //加技能点,试两次 |
| | | for (addTry = 0; addTry < 2; addTry++) |
| | | { |
| | | G.Instance.InputControl.MoveToAndClick(addSkillLevelButton.GetCenterPoint()); |
| | | result = FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { |
| | | return SkillCVHelper.SkillIsFullLevel(limitRect); |
| | | }); |
| | | if (result) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 格式化摆放技能栏 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool FormatSkillColumn() |
| | | { |
| | | //打开已学技能窗 |
| | | ZTRectangle studayTextRect = ZTRectangle.Empty; |
| | | if (!OpenStudaySkillWindow(out studayTextRect)) |
| | | { |
| | | G.Instance.DebugWriter("未指开已学技能窗口"); |
| | | return false; |
| | | } |
| | | |
| | | //技能栏全部技能移动已学技能窗 |
| | | if (!MoveSkillToStudayWindow(studayTextRect)) |
| | | { |
| | | G.Instance.DebugWriter("移动至已学技能窗口失败"); |
| | | return false; |
| | | } |
| | | |
| | | //技能窗内容分步移 |
| | | if (!MoveSkillToExpress(studayTextRect)) |
| | | { |
| | | G.Instance.DebugWriter("移动至快捷栏失败"); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 打开已学技能窗口 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool OpenStudaySkillWindow(out ZTRectangle studayTextRect) |
| | | { |
| | | studayTextRect = ZTRectangle.Empty; |
| | | ZTRectangle innerstudyTextRect = ZTRectangle.Empty; |
| | | Utility.Structs.ZTPoint openwindowButton = new Utility.Structs.ZTPoint(this.titleRect.Start.X + 194, this.titleRect.Start.Y + 517); |
| | | for (int i = 0; i < 2; i++) |
| | | { |
| | | if (this.CancelToken.IsCancellationRequested) |
| | | { |
| | | return false; |
| | | } |
| | | G.Instance.InputControl.MoveToAndClick(openwindowButton); |
| | | bool result = FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { |
| | | return SkillCVHelper.StudaySkillWindowIsOpen(out innerstudyTextRect,this.GameRect); |
| | | }, 200); |
| | | |
| | | if (result) |
| | | { |
| | | studayTextRect = innerstudyTextRect; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 从快捷栏向已学技能栏移动技能 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private bool MoveSkillToStudayWindow(ZTRectangle studayTextRect) |
| | | { |
| | | ZTRectangle targetRect = GetStudaySkillRect(studayTextRect, 27); |
| | | |
| | | for (int i = 0; i < 12; i++) |
| | | { |
| | | ZTRectangle expressRect = GetExpressSkillRect(i); |
| | | MoveSkill(expressRect.GetCenterPoint(), targetRect.GetCenterPoint()); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 识别出来的技能索引和在技能快捷栏中的对应关系 |
| | | /// 对应关系是-1的不放在快捷栏里 |
| | | /// </summary> |
| | | Dictionary<Int32, Int32> skillToExpressMap = new Dictionary<int, int>() { |
| | | { 4 ,0}, |
| | | { 13,1}, |
| | | { 8 ,2}, |
| | | { 9 ,3}, |
| | | { 15,4}, |
| | | { 12,5}, |
| | | |
| | | { 6 ,6}, |
| | | { 10,7}, |
| | | { 7 ,8}, |
| | | { 11,9}, |
| | | { 14,10}, |
| | | { 16,11} |
| | | |
| | | }; |
| | | /// <summary> |
| | | /// 从已学技能栏向快捷栏移动技能 |
| | | /// </summary> |
| | | /// <param name="studayTextRect"></param> |
| | | /// <returns></returns> |
| | | private bool MoveSkillToExpress(ZTRectangle studayTextRect) |
| | | { |
| | | int i = 0; |
| | | int count = 17; |
| | | while (i < count) |
| | | { |
| | | if (this.CancelToken.IsCancellationRequested) |
| | | { |
| | | return false; |
| | | } |
| | | //获取位置,并将鼠标移到位置,显示出技能名 |
| | | Utility.Structs.ZTPoint studayPoint = GetStudaySkillRect(studayTextRect, i).GetCenterPoint(); |
| | | G.Instance.InputControl.MoveTo(studayPoint.X, studayPoint.Y, false, false, false); |
| | | Thread.Sleep(1000); |
| | | |
| | | //识别 |
| | | Int32 skillIndex = 0;//技能索引 |
| | | ZTRectangle discenrnRect = new ZTRectangle(studayPoint.X - 150, this.GameRect.Start.Y, studayPoint.X, studayPoint.Y); |
| | | bool result = FuncUtils.TimeoutCancelableWrap(2000, this.CancelToken, () => { |
| | | return SkillCVHelper.GetSkillName(out skillIndex, discenrnRect); |
| | | }, 200); |
| | | if (result) |
| | | { |
| | | if (skillToExpressMap.ContainsKey(skillIndex)) |
| | | { |
| | | //要放到技能栏的位置 |
| | | Utility.Structs.ZTPoint to = GetExpressSkillRect(skillToExpressMap[skillIndex]).GetCenterPoint(); |
| | | MoveSkill(studayPoint, to); |
| | | count--; |
| | | continue; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | G.Instance.DebugWriter("识别技能错误,index=" + i.ToString()); |
| | | } |
| | | i++; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 移动技能 |
| | | /// </summary> |
| | | /// <param name="from"></param> |
| | | /// <param name="to"></param> |
| | | /// <returns></returns> |
| | | private bool MoveSkill(Utility.Structs.ZTPoint from, Utility.Structs.ZTPoint to) |
| | | { |
| | | //移动指定位置 |
| | | G.Instance.InputControl.MoveTo(from.X, from.Y, false, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration*2); |
| | | |
| | | //按下 |
| | | G.Instance.InputControl.Move(0, 0, true, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration * 3); |
| | | |
| | | //移到目标位置 |
| | | G.Instance.InputControl.MoveTo(to.X, to.Y, true, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration*2); |
| | | |
| | | |
| | | //松开 |
| | | G.Instance.InputControl.Move(0, 0, false, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration * 2); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 得到快捷栏技能定位 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <returns></returns> |
| | | private ZTRectangle GetExpressSkillRect(int index) |
| | | { |
| | | //x209,y488 |
| | | Int32 row = index / 6; |
| | | Int32 col = index % 6; |
| | | |
| | | int x = this.titleRect.Start.X + 209 + col * 33; |
| | | int y = this.titleRect.Start.Y + 488 + row * 33; |
| | | |
| | | return new ZTRectangle(x, y, x + 33, y + 33); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 得到已学技能栏定位 |
| | | /// </summary> |
| | | /// <param name="studayTextRect"></param> |
| | | /// <param name="index"></param> |
| | | /// <returns></returns> |
| | | private ZTRectangle GetStudaySkillRect(ZTRectangle studayTextRect, Int32 index) |
| | | { |
| | | //x:-122,y:44 |
| | | Int32 row = index / 7; |
| | | Int32 col = index % 7; |
| | | |
| | | int x = studayTextRect.Start.X + (-122) + col * 31; |
| | | int y = studayTextRect.Start.Y + 44 + row * 31; |
| | | |
| | | return new ZTRectangle(x, y, x + 31, y + 31); |
| | | } |
| | | } |
| | | } |
| | |
| | | using System.Threading; |
| | | using static RichCreator.Utility.CV.GroupCVHelper; |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Dnf; |
| | | |
| | | namespace RichCreator.Maps |
| | | namespace RichCreator.Maps.Test |
| | | { |
| | | /// <summary> |
| | | /// 测试地图 |
| | | /// </summary> |
| | | public class TestMap : MapInfo |
| | | { |
| | | /// <summary> |
| | | /// 游戏区域 |
| | | /// </summary> |
| | | public ZTRectangle GameRect { get; set; } |
| | | public TestMap(ZTRectangle gameRect, CancellationToken cancelToken) :base(MapType.Test, gameRect, cancelToken) |
| | | { |
| | | |
| | | public CancellationToken cancellationToken { get; set; } |
| | | |
| | | } |
| | | |
| | | private const bool isCreateGroup = true; |
| | | |
| | | public override ZTResult Start(ZTRectangle gameRect, CancellationToken cancelToken, Int32 runningStep) |
| | | { |
| | | this.GameRect = gameRect; |
| | | this.cancellationToken = cancelToken; |
| | | |
| | | WindowUtils.SetDnfToTop(); |
| | | public override ZTResult Start(Int32 runningStep) |
| | | {WindowUtils.SetDnfToTop(); |
| | | |
| | | |
| | | |
| | |
| | | } |
| | | //沉默一段时间 |
| | | Thread.Sleep(50000000); |
| | | CloseAllAlertWindow(this.cancellationToken, this.GameRect); |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | return ZTResult.Success; |
| | | } |
| | | |
| | |
| | | //点击创建 |
| | | G.Instance.InputControl.MoveToAndClick(okButtonRect.GetCenterPoint()); |
| | | |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.cancellationToken, () => { |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => { |
| | | //识别是否有我的队伍按钮 |
| | | return GroupCVHelper.ExistsMyGroupButton(out mygroupButtonRect, this.GameRect); |
| | | }); |
| | |
| | | { |
| | | G.Instance.InfoWriter("create group ok"); |
| | | //点击组队“确定”按钮 |
| | | result = FuncUtils.TimeoutCancelableWrap(15 * 60 * 1000,this.cancellationToken, () => { |
| | | result = FuncUtils.TimeoutCancelableWrap(15 * 60 * 1000,this.CancelToken, () => { |
| | | Utility.Structs.ZTPoint yes = Utility.Structs.ZTPoint.Empty; |
| | | Utility.Structs.ZTPoint no = Utility.Structs.ZTPoint.Empty; |
| | | bool retFind = GroupCVHelper.FindYaoqingZuduiWindow(out yes, out no, this.GameRect); |
| | |
| | | return true; |
| | | } |
| | | |
| | | Utility.Structs.ZTPoint searchButtonCenerPoint = searchButtonRect.GetCenterPoint(); |
| | | ZTPoint searchButtonCenerPoint = searchButtonRect.GetCenterPoint(); |
| | | //输入组名 |
| | | G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint (searchButtonCenerPoint.X-80, searchButtonCenerPoint.Y)); |
| | | DeleteAllChar(groupName.Length + 3); |
| | |
| | | |
| | | //查找组项 |
| | | ZTRectangle groupItemRect = ZTRectangle.Empty; |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.cancellationToken, () => { |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => { |
| | | //识别组项 |
| | | return GroupCVHelper.FindGroupItem(out groupItemRect, this.GameRect); |
| | | }); |
| | |
| | | |
| | | //查找是否打开成员列表窗 |
| | | ZTRectangle joinButtonRect = ZTRectangle.Empty; |
| | | result = FuncUtils.TimeoutCancelableWrap(5000, this.cancellationToken, () => { |
| | | result = FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => { |
| | | //识别是否打开成员列表窗 |
| | | return GroupCVHelper.FindGroupMemberWindow(out joinButtonRect, this.GameRect); |
| | | }); |
| | |
| | | G.Instance.InputControl.MoveToAndClick(joinButtonRect.GetCenterPoint()); |
| | | |
| | | //查找是否已经组队成功,30秒 |
| | | result = FuncUtils.TimeoutCancelableWrap(30000, this.cancellationToken, () => { |
| | | result = FuncUtils.TimeoutCancelableWrap(30000, this.CancelToken, () => { |
| | | //识别是否有我的队伍按钮 |
| | | return GroupCVHelper.ExistsMyGroupButton(out mygroupButtonRect, this.GameRect); |
| | | }); |
| | |
| | | ZTRectangle innerGroupWindowTextRect = ZTRectangle.Empty, innerSearchButtonRect = ZTRectangle.Empty, innerCreateGroupButton = ZTRectangle.Empty; |
| | | for (int i = 0; i < 2; i++) |
| | | { |
| | | CloseAllAlertWindow(this.cancellationToken, this.GameRect); |
| | | CloseAllAlertWindow(this.CancelToken, this.GameRect); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightSquarebrackets); |
| | | |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.cancellationToken, () => { |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => { |
| | | //识别队伍窗 |
| | | return GroupCVHelper.FindGroupWindow(out innerGroupWindowTextRect, out innerSearchButtonRect, out innerCreateGroupButton,out innerHasGroup, this.GameRect); |
| | | }); |
| | |
| | | { |
| | | //点击创建队伍 |
| | | G.Instance.InputControl.MoveToAndClick(createGroupButtonRect.GetCenterPoint()); |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.cancellationToken, () => { |
| | | bool result = FuncUtils.TimeoutCancelableWrap(5000, this.CancelToken, () => { |
| | | //识别创建队伍窗 |
| | | return GroupCVHelper.FindCreateGroupWindow(out innerCreateGroupWindowTextRect, out innerOkButtonRect, this.GameRect); |
| | | }); |
| | |
| | | <Reference Include="System.ServiceModel" /> |
| | | <Reference Include="System.Transactions" /> |
| | | <Reference Include="System.Web" /> |
| | | <Reference Include="System.Windows.Forms" /> |
| | | <Reference Include="System.Xml" /> |
| | | <Reference Include="Microsoft.CSharp" /> |
| | | <Reference Include="System.Core" /> |
| | |
| | | <Compile Include="..\Protocols\Richcreator.cs"> |
| | | <Link>Services\Richcreator.cs</Link> |
| | | </Compile> |
| | | <Compile Include="Dnf\DnfRole.cs" /> |
| | | <Compile Include="Dnf\IMiniMap.cs" /> |
| | | <Compile Include="Dnf\MapInfo.cs" /> |
| | | <Compile Include="Maps\Kalete\KaleteMap.cs" /> |
| | | <Compile Include="Maps\Kalete\KaleteMiniMap.cs" /> |
| | | <Compile Include="Maps\Kalete\OutOfBounds.cs" /> |
| | | <Compile Include="Maps\Lindong\LindongMiniMap.cs" /> |
| | | <Compile Include="Maps\Test\TestMap.cs" /> |
| | | <Compile Include="Maps\Skills\SkillMap.cs" /> |
| | | <Compile Include="PathFinding\Dijkstra.cs" /> |
| | | <Compile Include="PathFinding\Edge.cs" /> |
| | | <Compile Include="PathFinding\Node.cs" /> |
| | | <Compile Include="Maps\SkillSetting\SkillSettingMap.cs" /> |
| | | <Compile Include="Services\ServiceProvider.cs" /> |
| | | <Compile Include="StateMachines\ChannelStateMachine.cs" /> |
| | | <Compile Include="StateMachines\StateMachineBase.cs" /> |
| | |
| | | <Compile Include="Jobs\JobBase.cs" /> |
| | | <Compile Include="Jobs\JobMonitor.cs" /> |
| | | <Compile Include="Maps\Lindong\OutOfBounds.cs" /> |
| | | <Compile Include="Maps\Lindong\SingleEntryHouseSkill.cs" /> |
| | | <Compile Include="Models\RunningModel.cs" /> |
| | | <Compile Include="Models\RunningStep.cs" /> |
| | | <Compile Include="StateMachines\KillMonsterStateMachine.cs" /> |
| | | <Compile Include="StateMachines\MoveState.cs" /> |
| | | <Compile Include="StateMachines\SkillInfo.cs" /> |
| | | <Compile Include="StateMachines\SkillQueue.cs" /> |
| | | <Compile Include="Maps\HouseInfo.cs" /> |
| | | <Compile Include="Maps\Lindong\LindongMap.cs" /> |
| | | <Compile Include="Maps\MapInfo.cs" /> |
| | | <Compile Include="Models\RichCreatorConfig.cs" /> |
| | | <Compile Include="Jobs\WeGameJob.cs" /> |
| | | <Compile Include="Utilitys\AttackRectangle.cs" /> |
| | | <Compile Include="Utilitys\Utils.cs" /> |
| | | <Compile Include="ViewModels\ConfigViewModel.cs" /> |
| | | <Compile Include="ViewModels\NotificationObject.cs" /> |
| | | <Compile Include="ZTResult.cs" /> |
| | | <Page Include="MainWindow.xaml"> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | |
| | | <Name>RichCreator.Utility</Name> |
| | | </ProjectReference> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Folder Include="Maps\Kalete\" /> |
| | | </ItemGroup> |
| | | <ItemGroup /> |
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
| | | <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
| | | <PropertyGroup> |
| | |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.CV; |
| | | using RichCreator.Utility.Structs; |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Dnf; |
| | | using RichCreator.Maps.Kalete; |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.CV; |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Skills; |
| | | using RichCreator.Utility.Structs; |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Maps; |
| | | using RichCreator.Maps.Lindong; |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utilitys; |
| | | using static RichCreator.Utilitys.AttackRectangle; |
| | | using Utils = RichCreator.Utilitys.Utils; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Threading; |
| | | using ZTImage.Collections; |
| | | |
| | | namespace RichCreator.Jobs.StateMachines |
| | |
| | | public class KillMonsterStateMachine : StateMachineBase |
| | | { |
| | | private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数 |
| | | |
| | | private MapInfo map;//地图 |
| | | private HouseInfo house;//当前房间 |
| | | private ZTPoint miniMapStart;//小地图区域 |
| | | private ZTRectangle GameRect;//游戏区域 |
| | | private DnfRole role;//当前角色控制 |
| | | |
| | | private Int32 preHouseIndex = 0;//上一房间编号 |
| | | private MoveState moveState;//移动状态 |
| | | private OutOfBounds outOfBounds;//禁区 |
| | | private bool isSuccess;//退出结果 |
| | | |
| | |
| | | //当前状态 |
| | | private KillMonsterStates currentState = KillMonsterStates.Start; |
| | | //是否截图屏幕 |
| | | private bool captureScreen = false; |
| | | private bool needCaptureScreen = false; |
| | | |
| | | //怪 |
| | | private ZTPoint[] stateMonsters; |
| | |
| | | |
| | | //色彩hsv |
| | | private Image<Hsv, byte> hsvImage = null; |
| | | //取消令牌 |
| | | private CancellationToken cancellationToken = CancellationToken.None; |
| | | #region Find Door Info |
| | | //门坐标 |
| | | private ZTPoint stateDoorPosition; |
| | | //角色位置 |
| | | private ZTPoint stateRolePosition; |
| | | |
| | | //离开的门朝向 |
| | | private Direction stateDoorLevelDirect = Direction.None; |
| | | //定位点方框 |
| | | private MultiList<ZTRectangle, Int32> stateLocationRectangle = new MultiList<ZTRectangle, int>(); |
| | | |
| | | |
| | | //屏幕定位点 |
| | | private ParametersPoint stateScreenLocation = new ParametersPoint(); |
| | | |
| | | |
| | | |
| | | #endregion |
| | | |
| | | |
| | | public KillMonsterStateMachine(HouseInfo house, ZTPoint miniMapStart, ZTRectangle gameRect, Int32 preHouseIndex, Int32 runningStep, CancellationToken cancellationToken) |
| | | public KillMonsterStateMachine(MapInfo map,HouseInfo house, DnfRole role,Int32 preHouseIndex, Int32 runningStep) |
| | | { |
| | | this.runningStep = runningStep; |
| | | this.map = map; |
| | | this.house = house; |
| | | this.miniMapStart = miniMapStart; |
| | | this.GameRect = gameRect; |
| | | this.role = role; |
| | | this.runningStep = runningStep; |
| | | this.preHouseIndex = preHouseIndex; |
| | | this.cancellationToken = cancellationToken; |
| | | moveState = new MoveState(this.GameRect, this.house); |
| | | outOfBounds = new OutOfBounds(this.GameRect, moveState); |
| | | hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1); |
| | | |
| | | outOfBounds = new OutOfBounds(map.GameRect, role); |
| | | hsvImage = new Image<Hsv, byte>(map.GameRect.End.X - map.GameRect.Start.X + 1, map.GameRect.End.Y - map.GameRect.Start.Y + 1); |
| | | } |
| | | |
| | | |
| | |
| | | private void SetState(KillMonsterStates current, bool capture) |
| | | { |
| | | currentState = current; |
| | | captureScreen = capture; |
| | | needCaptureScreen = capture; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | } |
| | | |
| | | //定位方框列表 |
| | | MultiList<ZTRectangle, Int32> locationRectangles = new MultiList<ZTRectangle, int>(); |
| | | |
| | | while (true) |
| | | { |
| | | if (cancellationToken.IsCancellationRequested) |
| | | if (map.CancelToken.IsCancellationRequested) |
| | | { |
| | | G.Instance.DebugWriter("取消刷图"); |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | return ZTResult.Cancel; |
| | | } |
| | | |
| | | if (DateTime.Now > expireTime) |
| | | { |
| | | G.Instance.DebugWriter("刷图超时"); |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | return ZTResult.Timeout; |
| | | } |
| | | |
| | | if (captureScreen) |
| | | if (needCaptureScreen) |
| | | { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | |
| | | image.Dispose(); |
| | | } |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(GameRect.Start.X, GameRect.Start.Y, GameRect.End.X - GameRect.Start.X + 1, GameRect.End.Y - GameRect.Start.Y + 1)); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(map.GameRect.Start.X, map.GameRect.Start.Y, map.GameRect.End.X - map.GameRect.Start.X + 1, map.GameRect.End.Y - map.GameRect.Start.Y + 1)); |
| | | imageIsChange = true; |
| | | } |
| | | } |
| | |
| | | { |
| | | case KillMonsterStates.Start: |
| | | //开始 |
| | | SingleEntryHouseSkill.ReleaseSkill(this.house.Index, this.preHouseIndex, this.moveState); |
| | | this.map.EntryHousePrework(this.house.Index, this.preHouseIndex); |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | break; |
| | | case KillMonsterStates.IsLastHouse: |
| | |
| | | break; |
| | | case KillMonsterStates.HasRewardWindow: |
| | | //是否有奖励界面 |
| | | if (DnfCVHelper.IsJiangli(image, this.GameRect)) |
| | | if (DnfCVHelper.IsJiangli(image, map.GameRect)) |
| | | { |
| | | SetState(KillMonsterStates.TurnAroundCard, false); |
| | | } |
| | |
| | | break; |
| | | case KillMonsterStates.IsCompletePage: |
| | | //是否刷完界面 |
| | | if (DnfCVHelper.IsCompleteRoom(image, this.GameRect)) |
| | | if (DnfCVHelper.IsCompleteRoom(image, map.GameRect)) |
| | | { |
| | | this.isSuccess = true; |
| | | SetState(KillMonsterStates.Exit, false); |
| | |
| | | //主角 |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | |
| | | |
| | | //定位点 |
| | | if (!DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.GameRect)) |
| | | if (!DnfCVHelper.GetLocationPoint(out locationRectangles, hsvImage, map.GameRect)) |
| | | { |
| | | //找不到定位点 |
| | | G.Instance.InfoWriter("找不到定位点"); |
| | |
| | | break; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.GameRect); |
| | | if (this.stateRolePosition .Equals( ZTPoint.Empty)) |
| | | this.stateScreenLocation = new ParametersPoint(locationRectangles[0].Item1.GetCenterPoint(), locationRectangles[0].Item2); |
| | | |
| | | ZTPoint rolePosition = DnfCVHelper.FindRole(hsvImage, map.GameRect); |
| | | if (rolePosition .Equals( ZTPoint.Empty)) |
| | | { |
| | | SetState(KillMonsterStates.FindRoleMove, false); |
| | | } |
| | | else |
| | | { |
| | | if (this.moveState.IsFindRoleMoving) |
| | | if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.FindRoleMove)) |
| | | { |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | } |
| | | role.UpdatePosition(rolePosition); |
| | | SetState(KillMonsterStates.FindMonster, false); |
| | | } |
| | | break; |
| | |
| | | break; |
| | | case KillMonsterStates.FindMonster: |
| | | //找怪 |
| | | this.stateMonsters = LindongCVHelper.FindMonster(hsvImage, this.GameRect); |
| | | this.stateMonsters = LindongCVHelper.FindMonster(hsvImage, map.GameRect); |
| | | |
| | | if (this.stateMonsters.Length > 0) |
| | | { |
| | |
| | | break; |
| | | case KillMonsterStates.PickupThing: |
| | | //拾取物品 |
| | | SetState(KillMonsterStates.FindDoor, false); |
| | | SetState(KillMonsterStates.ToNextGatePoint, false); |
| | | //todo: PickupThing(); |
| | | break; |
| | | case KillMonsterStates.ToNextGatePoint: |
| | | //移到进门点 |
| | | SetState(KillMonsterStates.FindDoor, false); |
| | | //todo:ToNextGatePoint |
| | | break; |
| | | case KillMonsterStates.FindDoor: |
| | | //查找门, 是否找到门 |
| | |
| | | case KillMonsterStates.Exit: |
| | | //结束 |
| | | G.Instance.DebugWriter("退出状态"); |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | if (this.isSuccess) |
| | | { |
| | | return ZTResult.Success; |
| | |
| | | /// </summary> |
| | | private void FindRoleMove() |
| | | { |
| | | this.moveState.FindRoleMove(); |
| | | SetState(KillMonsterStates.FindRole, true); |
| | | |
| | | //if (this.stateMonsters.Length > 0) |
| | | //if (this.stateMonsters != null && this.stateMonsters.Length > 0) |
| | | //{ |
| | | // this.moveState.StopMove(); |
| | | // this.role.StopMove(); |
| | | // G.Instance.DebugWriter("找不到角色,Send X"); |
| | | // G.Instance.InputControl.PressKey(1000, HIDCode.X); |
| | | // SetState(KillMonsterStates.FindMonster, true); |
| | | // SetState(KillMonsterStates.FindRole, true); |
| | | |
| | | // return; |
| | | //} |
| | | //else |
| | | //{ |
| | | // this.moveState.FindRoleMove(); |
| | | // SetState(KillMonsterStates.IsLastHouse, true); |
| | | //} |
| | | this.role.FindRoleMove(); |
| | | SetState(KillMonsterStates.FindRole, true); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | private void PickupThing() |
| | | { |
| | | //拾取物品,获取最近一个物品位置并步行过去 |
| | | ZTPoint thingItemPosition = GetNearlyThingItem(image, stateRolePosition); |
| | | ZTPoint thingItemPosition = GetNearlyThingItem(image, role.Position); |
| | | if (!thingItemPosition .Equals( ZTPoint.Empty)) |
| | | { |
| | | if (this.moveState.IsMoving && !this.moveState.IsPickupMoving) |
| | | if (this.role.IsMoving && !this.role.IsMoveIntent(Utility.Dnf.MoveIntent.PickupMove)) |
| | | { |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | } |
| | | |
| | | this.moveState.PickupMove(this.stateRolePosition, thingItemPosition); |
| | | this.role.PickupMove(this.role.Position, thingItemPosition); |
| | | //return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | |
| | | if (this.moveState.IsPickupMoving) |
| | | if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.PickupMove)) |
| | | { |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | } |
| | | } |
| | | |
| | |
| | | private void FindDoor() |
| | | { |
| | | //查找真实的门 |
| | | this.stateDoorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect, hsvImage, this.house.DoorDirection, this.GameRect); |
| | | this.stateDoorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect, hsvImage, this.house.DoorDirection, map.GameRect); |
| | | if (!this.stateDoorPosition .Equals(ZTPoint.Empty)) |
| | | { |
| | | //找到门,向门移动 |
| | | if (this.moveState.IsFindDoorMoving) |
| | | if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.FindDoorMove)) |
| | | { |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | } |
| | | G.Instance.InfoWriter("已找到门,位置:" + stateDoorPosition.ToString()); |
| | | SetState(KillMonsterStates.EntryDoor, false); |
| | |
| | | case Direction.Up: |
| | | //门在上方 |
| | | limitLine = stateDoorPosition.Y + YLevelOffset; |
| | | if (stateRolePosition.Y < limitLine) |
| | | if (role.Position.Y < limitLine) |
| | | { |
| | | //下移 |
| | | this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y)); |
| | | this.role.SyncMove(new ZTPoint(0, limitLine - role.Position.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | diff = stateDoorPosition.X - role.Position.X; |
| | | this.role.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.GameRect.Start.Y - stateRolePosition.Y)); |
| | | this.role.SyncMove(new ZTPoint(0, map.GameRect.Start.Y - role.Position.Y)); |
| | | break; |
| | | |
| | | case Direction.Right: |
| | | //门在右侧 |
| | | limitLine = stateDoorPosition.X - XLevelOffset; |
| | | if (stateRolePosition.X > limitLine) |
| | | if (role.Position.X > limitLine) |
| | | { |
| | | //如果角色位于门右侧,先向左移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | this.role.SyncMove(new ZTPoint(limitLine - role.Position.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | diff = stateDoorPosition.Y - role.Position.Y; |
| | | this.role.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.GameRect.End.X - stateRolePosition.X, 0)); |
| | | this.role.SyncMove(new ZTPoint(map.GameRect.End.X - role.Position.X, 0)); |
| | | break; |
| | | |
| | | case Direction.Bottom: |
| | | //门在下方 |
| | | limitLine = stateDoorPosition.Y - YLevelOffset; |
| | | if (stateRolePosition.Y > limitLine) |
| | | if (role.Position.Y > limitLine) |
| | | { |
| | | //如果角色在门下方,先向上移 |
| | | this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y)); |
| | | this.role.SyncMove(new ZTPoint(0, limitLine - role.Position.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | diff = stateDoorPosition.X - role.Position.X; |
| | | this.role.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.GameRect.End.Y - stateRolePosition.Y)); |
| | | this.role.SyncMove(new ZTPoint(0, map.GameRect.End.Y - role.Position.Y)); |
| | | break; |
| | | |
| | | case Direction.Left: |
| | | //门在左侧 |
| | | limitLine = stateDoorPosition.X + XLevelOffset; |
| | | if (stateRolePosition.X < limitLine) |
| | | if (role.Position.X < limitLine) |
| | | { |
| | | //如果角色位于门左侧,先向右移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | this.role.SyncMove(new ZTPoint(limitLine - role.Position.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | diff = stateDoorPosition.Y - role.Position.Y; |
| | | this.role.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.GameRect.Start.X - stateRolePosition.X, 0)); |
| | | this.role.SyncMove(new ZTPoint(map.GameRect.Start.X - role.Position.X, 0)); |
| | | break; |
| | | } |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | |
| | | private void FindDoorMove() |
| | | { |
| | | Int32 areaID = 0; |
| | | if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID)) |
| | | if (this.outOfBounds.InOutOfBound(this.house.Index, role.Position, out areaID)) |
| | | { |
| | | this.outOfBounds.MoveToCommonBound(areaID); |
| | | } |
| | | else |
| | | { |
| | | this.moveState.FindDoorMove(stateRolePosition); |
| | | this.role.FindDoorMove(role.Position); |
| | | } |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | } |
| | |
| | | |
| | | //计算攻击移动距离 |
| | | bool needMove = false; |
| | | attackMoveDistance = AttackRectangle.GetMoveDistance(this.GameRect, stateRolePosition, stateMonsters, attackSkill, out roleDirection, out needMove); |
| | | attackMoveDistance = AttackRectangle.GetMoveDistance(map.GameRect, role.Position, stateMonsters, attackSkill, out roleDirection, out needMove); |
| | | if (!needMove) |
| | | { |
| | | G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", attackMoveDistance.ToString())); |
| | |
| | | { |
| | | G.Instance.InputControl.PressKey(100, roleDirection); |
| | | } |
| | | this.moveState.StopMove(); |
| | | this.role.StopMove(); |
| | | |
| | | |
| | | |
| | |
| | | { |
| | | SkillInfo attackSkill = this.house.Skills.SyncPeek(); |
| | | //没有移动,可能有障碍物 |
| | | if (stateRolePosition .Equals( this.roleLastPosition)) |
| | | if (role.Position .Equals( this.roleLastPosition)) |
| | | { |
| | | if (FindRoleLastNoMoveStart && (DateTime.Now - FindRoleLastNoMoveTime).TotalMilliseconds > NoMoveMaxMillSecond) |
| | | { |
| | | //开始计时 并且 超过最大未移动容忍时间 |
| | | G.Instance.DebugWriter("find role no mvoe:" + stateRolePosition.ToString()); |
| | | this.moveState.StopMove(); |
| | | G.Instance.DebugWriter("find role no mvoe:" + role.Position.ToString()); |
| | | this.role.StopMove(); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X); |
| | | FindRoleLastNoMoveTime = DateTime.Now; |
| | | } |
| | |
| | | else |
| | | { |
| | | //移动了 取消计时 |
| | | this.roleLastPosition = stateRolePosition; |
| | | this.roleLastPosition = role.Position; |
| | | FindRoleLastNoMoveStart = false; |
| | | } |
| | | |
| | | G.Instance.DebugWriter("attack move :" + attackMoveDistance.ToString() + ",role:" + stateRolePosition.ToString() + ",monster1:" + stateMonsters[0].ToString() + ",skill:" + attackSkill.Key.ToString()); |
| | | this.moveState.AttackMove(attackMoveDistance); |
| | | G.Instance.DebugWriter("attack move :" + attackMoveDistance.ToString() + ",role:" + role.Position.ToString() + ",monster1:" + stateMonsters[0].ToString() + ",skill:" + attackSkill.Key.ToString()); |
| | | this.role.AttackMove(attackMoveDistance); |
| | | SetState(KillMonsterStates.FindRole, true); |
| | | } |
| | | #endregion |
| | |
| | | /// <returns></returns> |
| | | public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image, ZTPoint rolePosition) |
| | | { |
| | | List<ZTPoint> points = DnfCVHelper.GetThingItemPoints(image, this.GameRect); |
| | | List<ZTPoint> points = DnfCVHelper.GetThingItemPoints(image, map.GameRect); |
| | | if (points.Count <= 0) |
| | | { |
| | | return ZTPoint.Empty; |
| | |
| | | { |
| | | Thread.Sleep(2000); |
| | | Int32 number = RandomUtils.G(1, 4); |
| | | ZTPoint willPosition = this.GameRect.Start.Add(CardList[number - 1]); |
| | | ZTPoint willPosition = map.GameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10)); |
| | | |
| | | //判断黄金版是否可以翻 |
| | | if (DnfCVHelper.HasMowangqiyueCard(this.GameRect)) |
| | | if (DnfCVHelper.HasMowangqiyueCard(map.GameRect)) |
| | | { |
| | | number = RandomUtils.G(5, 8); |
| | | willPosition = this.GameRect.Start.Add(CardList[number - 1]); |
| | | willPosition = map.GameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10)); |
| | | } |
| | | |
| | |
| | | /// <returns></returns> |
| | | private bool HouseIsChange() |
| | | { |
| | | Int32 houseIndex; |
| | | if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart)) |
| | | Int32 houseIndex = 0; |
| | | if (!map.MiniMap.GetCurrentHouseIndexWaitTimeout(out houseIndex, image, map.CancelToken, 30 * 1000)) |
| | | { |
| | | //得不到房间 |
| | | if (!FuncUtils.TimeoutCancelableWrap(30 * 1000, cancellationToken, () => |
| | | { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(GameRect.Start.X, GameRect.Start.Y, GameRect.End.X - GameRect.Start.X + 1, GameRect.End.Y - GameRect.Start.Y + 1)); |
| | | return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart); |
| | | } |
| | | }, 50)) |
| | | { |
| | | throw new Exception("找不到默认房间"); |
| | | } |
| | | throw new Exception("找不到默认房间"); |
| | | } |
| | | if (houseIndex != this.house.Index) |
| | | { |
| | | this.moveState.StopMove(); |
| | | return true; |
| | | } |
| | | return false; |
| | |
| | | FindRoleMove,//让主角移动(原:有怪攻击一下,无怪移动一下) |
| | | FindMonster,//找怪 |
| | | PickupThing,//拾取物品 |
| | | ToNextGatePoint,//移到进门点 |
| | | FindDoor,//查找门, 是否找到门 |
| | | EntryDoor,//向门移动, 进门 |
| | | FindDoorMove,//找门移动 |
| | |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using RichCreator.Utility.Skills; |
| | | using RichCreator.Utility.Maps; |
| | | |
| | | namespace RichCreator.Utilitys |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 移动优化级 |
| | | /// </summary> |
| | | public enum MovePriority |
| | | { |
| | | Quantity,//数量集中为高优先级 |
| | | Nearly//近为高优先级 |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | using System.Drawing; |
| | | using System.Reflection.Emit; |
| | | using System.Reflection; |
| | | using Tesseract; |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | |
| | | namespace test |
| | | { |
| | |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | class Program |
| | | { |
| | | |
| | | |
| | | static void Main(string[] args) |
| | | { |
| | | person a = new person(235, "a0"); |
| | | person b = new person(12, "b1"); |
| | | person c = new person(34, "c2"); |
| | | person d = new person(45, "d3"); |
| | | person e = new person(56, "e4"); |
| | | Dijkstra<person> dij = new Dijkstra<person>(); |
| | | dij.AddVertex(a, new Dictionary<person, int>() { { b, 7 }, { d, 8 } }); |
| | | dij.AddVertex(b, new Dictionary<person, int>() { { a, 7 }, { c, 2 },{ d,2} ,{ e,3} }); |
| | | dij.AddVertex(c, new Dictionary<person, int>() { { b, 8 }, { e, 6 } }); |
| | | dij.AddVertex(d, new Dictionary<person, int>() { { a, 8 },{ b,2} }); |
| | | dij.AddVertex(e, new Dictionary<person, int>() { { b, 1 },{ c,2} }); |
| | | |
| | | dij.ShortestPath(d, e).ForEach(x => Console.WriteLine(x)); |
| | | ZTImage.Diagnostics.CodeTimer.Timer("dij", 10000, () => |
| | | { |
| | | //g.ShortestPath('A', 'H').ForEach(x => Console.WriteLine(x)); |
| | | dij.ShortestPath(a, b); |
| | | |
| | | Image<Rgb, byte> image = RichCreator.Utility.Captures.ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | int i = 0; |
| | | ZTImage.Diagnostics.CodeTimer.Timer("test", 100000, () => { |
| | | |
| | | byte b1 = image.Data[i % 53, i % 37,0]; |
| | | byte b2 = image.Data[i % 53, i % 37, 1]; |
| | | Int32 total = b1 + b2; |
| | | |
| | | if (total > 300000) |
| | | { |
| | | Console.WriteLine("oik"); |
| | | } |
| | | }); |
| | | //person a = new person(235, "a0"); |
| | | //person b = new person(12, "b1"); |
| | | //person c = new person(34, "c2"); |
| | | //person d = new person(45, "d3"); |
| | | //person e = new person(56, "e4"); |
| | | //Dijkstra<person> dij = new Dijkstra<person>(); |
| | | //dij.AddVertex(a, new Dictionary<person, int>() { { b, 7 }, { d, 8 } }); |
| | | //dij.AddVertex(b, new Dictionary<person, int>() { { a, 7 }, { c, 2 },{ d,2} ,{ e,3} }); |
| | | //dij.AddVertex(c, new Dictionary<person, int>() { { b, 8 }, { e, 6 } }); |
| | | //dij.AddVertex(d, new Dictionary<person, int>() { { a, 8 },{ b,2} }); |
| | | //dij.AddVertex(e, new Dictionary<person, int>() { { b, 1 },{ c,2} }); |
| | | |
| | | //dij.ShortestPath(d, e).ForEach(x => Console.WriteLine(x)); |
| | | //ZTImage.Diagnostics.CodeTimer.Timer("dij", 10000, () => |
| | | //{ |
| | | // //g.ShortestPath('A', 'H').ForEach(x => Console.WriteLine(x)); |
| | | // dij.ShortestPath(a, b); |
| | | |
| | | //}); |
| | | |
| | | //Bitmap bm = new Bitmap("d:\\t2.png"); |
| | | //var ocr = new TesseractEngine("./tessdata", "eng", EngineMode.TesseractAndCube); |
| | | |
| | | //Page page=ocr.Process(bm); |
| | | //string text=page.GetText(); |
| | | //Console.WriteLine("识别出文字:" + text); |
| | | |
| | | |
| | | Console.ReadKey(); |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <packages> |
| | | <package id="EMGU.CV" version="4.1.0.3420" targetFramework="net45" /> |
| | | <package id="Tesseract" version="3.3.0" targetFramework="net45" /> |
| | | <package id="ZedGraph" version="5.1.7" targetFramework="net45" /> |
| | | <package id="ZTImage" version="2.1.16" targetFramework="net45" /> |
| | | </packages> |
| | |
| | | <Reference Include="System.Data" /> |
| | | <Reference Include="System.Net.Http" /> |
| | | <Reference Include="System.Xml" /> |
| | | <Reference Include="Tesseract, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL"> |
| | | <HintPath>..\packages\Tesseract.3.3.0\lib\net45\Tesseract.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="ZedGraph, Version=5.1.7.430, Culture=neutral, PublicKeyToken=02a83cbd123fcd60, processorArchitecture=MSIL"> |
| | | <HintPath>..\packages\ZedGraph.5.1.7\lib\net35-Client\ZedGraph.dll</HintPath> |
| | | </Reference> |
| | |
| | | <None Include="App.config" /> |
| | | <None Include="packages.config" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ProjectReference Include="..\RichCreator.Utility\RichCreator.Utility.csproj"> |
| | | <Project>{ceeff4d3-cc6f-4afe-85fe-e590c87a9972}</Project> |
| | | <Name>RichCreator.Utility</Name> |
| | | </ProjectReference> |
| | | </ItemGroup> |
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
| | | <Import Project="..\packages\EMGU.CV.4.1.0.3420\build\EMGU.CV.targets" Condition="Exists('..\packages\EMGU.CV.4.1.0.3420\build\EMGU.CV.targets')" /> |
| | | <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
| | |
| | | <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText> |
| | | </PropertyGroup> |
| | | <Error Condition="!Exists('..\packages\EMGU.CV.4.1.0.3420\build\EMGU.CV.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EMGU.CV.4.1.0.3420\build\EMGU.CV.targets'))" /> |
| | | <Error Condition="!Exists('..\packages\Tesseract.3.3.0\build\Tesseract.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Tesseract.3.3.0\build\Tesseract.targets'))" /> |
| | | </Target> |
| | | <Import Project="..\packages\Tesseract.3.3.0\build\Tesseract.targets" Condition="Exists('..\packages\Tesseract.3.3.0\build\Tesseract.targets')" /> |
| | | </Project> |