From 0220cedf1091ae31e480aa1aeb2412f1933c6d71 Mon Sep 17 00:00:00 2001 From: Warren Ulrich Date: Sat, 10 Jun 2023 00:53:11 -0700 Subject: [PATCH] Initial commit --- .gitignore | 2 + CMakeLists.txt | 48 ++++++++ collision_map.png | Bin 0 -> 3214 bytes collision_map_plane_0.png | Bin 0 -> 37476 bytes collision_map_plane_1.png | Bin 0 -> 1661 bytes collision_map_plane_2.png | Bin 0 -> 1192 bytes image_gen.go | 134 +++++++++++++++++++++ src/main.cpp | 247 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 431 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 collision_map.png create mode 100644 collision_map_plane_0.png create mode 100644 collision_map_plane_1.png create mode 100644 collision_map_plane_2.png create mode 100644 image_gen.go create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01f9cb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +.vscode/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2c2ae47 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.26) + +project(collision_cacher) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_SHARED_LINKER_FLAGS "-Os -s -m32 -static-libgcc -static-libstdc++ -static") +set(CMAKE_SHARED_LIBRARY_PREFIX "") + +if (NOT DEFINED ALPACABOT_DIR) + set(ALPACABOT_DIR $ENV{USERPROFILE}\\AlpacaBot) +endif() + +if (NOT DEFINED ALPACABOT_INCLUDE_DIR) + set(ALPACABOT_INCLUDE_DIR ${ALPACABOT_DIR}\\Include) +endif() + +if (NOT DEFINED ALPACABOT_LIB_DIR) + set(ALPACABOT_LIB_DIR ${ALPACABOT_DIR}\\Library) +endif() + +if (NOT DEFINED ALPACABOT_SCRIPT_DIR) + set(ALPACABOT_SCRIPT_DIR ${ALPACABOT_DIR}\\Script\\Local) +endif() + + +set(SOURCE_FILES + src/main.cpp +) + +add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES}) + +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${ALPACABOT_SCRIPT_DIR}/${PROJECT_NAME} +) + +target_include_directories(${PROJECT_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${ALPACABOT_INCLUDE_DIR} +) + +target_link_directories(${PROJECT_NAME} PRIVATE + ${ALPACABOT_LIB_DIR} +) + +target_link_libraries(${PROJECT_NAME} PRIVATE + AlpacaLibrary +) diff --git a/collision_map.png b/collision_map.png new file mode 100644 index 0000000000000000000000000000000000000000..4f45ad966f152927a9228b0193540880b237adca GIT binary patch literal 3214 zcmV;93~}>`P)D-FLWGOsw&BNkaj@VX9q_2rxADf>rk?3EI|NO? zXTVxx(RVl&Hu2WUaiFg9OSX)Nm_%nSqfE5bF`PRFI~SCp(CU7*PVDoWfRYp7ZKnT1)A=nVo+Ryvg@1 zA?_!$kGy)Van{&3#V$bzMGj|SW|ChA%=mZFnB1d$z6UEThzn^>1?B(JcKD31)zsU>c=q!Synu3ml;gn8=;>8h+1$|8P7bm7XD0QZL=*bw1| zeE%L~%-RuJd!ec$*bLe>8arYZG?Y;WBdNwFtfD_c8CoN*fj1G>Jr!+Ih2`H90(@eR zu%?TB8z6R;wU{emG=|7x-iJKh4K=OWyLGfC!+2gn23KnVlJ)_+Xs{(ss>q*ScklOi zQbj?MKQZzjO(BAeVv-v}kPtqR-Qn^d7wgN2*tLqxqPC4vQxQtWKVe0qKGgkYEl4Y{ z4VhCFBK83hSBG`S|3;>mxrs{@n8dnCGZ2sv*w&fVb~i+Il=zKS+IS^9!WGgQ@#BhB zQA&^yLqOEB8eUqAKvM*{$r$=zNRpr?p$64oj@;H-FL!MtYj)ItSAdv)9&f1VTs& zCTyHk7G;ewZW|MkU_}0RFclawB~iIEcX48qZ{0YUEs!Av8M6PV&im0K{V%}`B4UW) z?MpHM;3#`U&BfqOFxte_%|I<*z?67$*j;U@WkiL9+*)(x+r>+YVipuSDewQCEfGVd zMT6-fUCc`YP+TP^B6A<-=D5OQ?^)Va%4Ov1QX{U;OCrg}4bbs=A$PV=%LV=%F`w$2 z;0Ky+2pkKQl2AW?_+p`l$<8tBCb7WcEJ4dY+hI6YY!D9IqnjFXr@aNK9pz#f$rSW^ zxThA@C22z%C+(~H!Bwdy8W1%mo3sIaNIb8WD;4A`g*OGYuzu%cwlW@Vy;B(+s4ueL zf?Qm2*!N>(b^0;EKVr4$_wfJA$h$JT1JGXV>a;vM8JVgOlX6& z+}6h+<4!~j%OYg-5OFl@rM5@HzLFK6MimHVB6M14CSoRTP31vP9q%>qC!%_UlxJ35 z@3)2uK&rl49d2Q;oj|6lj|0R{XAm(XXgN|)o9*R={X&lG@enDuu%@03F+BPK{9ag7 zd|;*~Qr(<4Ivp?Yy3JSIHnFB0BY~Q9(F!WxsTYdMnVDh!8b~r?MLtxM*K?B#GDGaM zx59QqGuSIO`j-3?L8YDz0e-6%GphTe7_>V7D2JgfnlzgOth|okxz+S}^b--Vbz|wD z4u~R_g&RHeqiK`~XJ%OsrVz3CQ>Zt`0QdDVMTP z?&H&TkQ;nf5ceWc;wtQ=?`uJQXvvod?4G*W7M2BPSA9h%-7KieLV;u}09VL>av%sn8{<{1 zl2|BB&U4bKKA$!5Jp8%OM<9@tVlLCD z4RoXs7vA3K`q=EFry+Yvjj+JNnSe&HBW5(DCO@Y$DOH=@_=ML^Y&?tHZ9!l!A%f=c?n46ijG&M-?J`7gH#nz)wiCTz zgp)M8$8N7j%Ddun4_$1VC$@t${!_x-3VS``y-b}<0Vx^qyEbV?bH^|<(&fcwn4t&j zk<*Y-+5T0yY5DHpAzHle>ielTs{nbh%Q)YE+YFK!jf`N};wwnIqV)B`WDxcc#u2(^ zn^?-j!$aabq%Ue&*$US@3vRfR)lSCa!MGt+AlCFOFdmH}ccXJW@+L{Xh>S4Fu}pkd z#Z9O37bMTTTcawN&uF@mBAPywW7${I2&yxn6xvCTN@hS1%FQixd-TLe%ib~6s|0*C zmpmW^O`xbcZ+08Ly=4FYtb3#PN&?^o7`F$K2SzJO+GVE>X?B6x7Rp!Z7_u*KD1g&D zGtQg8%?mr`4|u77&ihZEfa~plEtC_dec#ZtAdp0bqVNDntzCvQXS-^k=hisXvp#DY zwKE2k;-A%3DYakg68VO-%OWGX?r-AEqh)5iuLx?SIRj5K2>9>5h>)qhD9ZOOq0%eK zZ8if$(O^1#Q+j^|g&Dc=0Z>tCq=;YMY{p~TEi!FQ6{8#}hKyww_-brnC0NAw&`pC7 z@Skcz>sBe0(K{NaA{!FhSpV$+8S-sZR`tfQ_R>ASEgFdv^DZIX;!w@F^Jl1 zgx0JI%&7vtX6FJKad$3kk2UcLL#vAX4>KvigyJ1NGl^oe6QV7yilm|DF@<}pOZACm z&%Veb!T!Q1ad7*6X<@Dky1S0NZj=%{KCP-c{B0Ex_3C%JbI^J#Q@hIfgj^}GR~G|$ zkGGjnSUf8~4PCoqbczAkLOgS|NA(CN8t{GG7jE%w*ia`HqE-^5P^qT!3>FW)|C}dk zEJIpD&yyDl;yNdfhf~S{BREQrV}gWAV!tCDTG8fCzGWM*^oiQ&VvL;5k(~Db|VAkgI)RRD+zN8r03M{F0)V{FBs5Tv{ zjU+`IqTzS~R_v?lY;dGjdg&e2oqYl7SO%p6K}M|jc81+5%S=(zgi*IwA)gf@qyWas z!}kVNInwxdmV=8MxZcq>qikGdcU5)&1pom5|M)y%_TGZ3)c^nh07*qoM6N<$g4NR+ At^fc4 literal 0 HcmV?d00001 diff --git a/collision_map_plane_0.png b/collision_map_plane_0.png new file mode 100644 index 0000000000000000000000000000000000000000..a5de09efee45c26c9a959234e282d9f729dc9749 GIT binary patch literal 37476 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 literal 0 HcmV?d00001 diff --git a/collision_map_plane_1.png b/collision_map_plane_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d538e4bea861e3a7820f63f0240387935ec778a5 GIT binary patch literal 1661 zcmchYSvVUA5XV#Z**em+MW}8OL20`dpE?@16+*R*b<|O;=xUMFRg12h#PZd-P18{F zRoyDB+F--lrH&S9D52C*B<@HgBAe~Y_F|N|Hd&fUyGO$rqjwdrck&D#!*xI&_<7q)>vg0*tRZ?G1|Nfn64 zVKj|IMF`#y#JW{ei#XK$8B9?$Sx|NzvivkoW*6VKIkAZ;!ZR5`NdE55#RDsI{k#Mj zW}Bl6XsO_@=QGm8@50LPr1&Cj}LQ}_i9Mq7YPKHajmEHURlhRkT@s6x+4q~AxXFH~S;0k;SUjGJc)gRsO zXG$rEk(g6@8d_;f!*Q{^M3;eyE@RW(14P|BaCnqq+hH=GVMI+*43?IPIDHx@BlC6S zQ@fO1DU~m?t^Tsr*2!4Q0g|e#|0A)LUNLbVp>cgnpdY*< z-RY`zgQwAP(Q|d|E`t-t_`~-Ci*eMSfg5Ju^C(^=^{>=WRY(?AoXeV)NWLJsUWkpF zn&iO8$X(>E{f(xzJq2W_x<(>x*?YtIlG7-MUU6n5-Rs4e#Ew}}T7S$bSWvTpN0Btq zdnwSEg^wv0U|5(wCL80b7tG`CZnWI=1$CJ(x6oH6o5AOkS#5Tc z>2{5g@7I7k9rTye#(`M@hM0CpX4&VP(n$0S&O4U*qx>Vj2~69wMO7>M^1@O&^}(`p z5xz@{8w;O{^B419|GqNlZe~0NLv8d~V5Y{F zFD2QH*s%F!_AI! z_)+{V>{ySEp2TS6-`BK((c%c|rkQ*QEd}T_w7lcx&Pt5g!JQ+pa?Wl~aTDDwwFsE2#U5st8 z4%peh7Fzi$#ODrwQJyehPjsY#GZT80#dPJax2;BmsAd>cyh65=?w9NxK;F404@&h K_6@MW`~Lv{g!Hfg literal 0 HcmV?d00001 diff --git a/collision_map_plane_2.png b/collision_map_plane_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2f7aa9bdefd1d6845e5e03dcc8bb319b85ce27 GIT binary patch literal 1192 zcmeAS@N?(olHy`uVBq!ia0vp^8-Vy62OE%_H^1XO0|QIGr;B4q#hf>H8}k-#9#wk{NNWo-Ok;rHm)mdHoT?DwBjDBHj5_p9dhx}oE$|#J_%-@`x<-`%#xXe-(J)%4EBjC z`>yITNq6Rf?KXlp?if6Hcq_EWCBmrj{K4y0oqwOr`EW(}!Nu#jOqH{yPwF(Ye(?Iq z+kbxd!z+HybWPJ&Jf*s`YH$2|#e<)96g$)s7V%COsMcZDv5h#w!giyZ)5nBS*ca+3 zdNTKYt7G84(z$+muN=FzQDdiCLc`t}1Kf)~4`Vh=9 zBO|`rzCj`NJ^P168|RB<{%`YCE13OGw{%uClj--KCo4T>|J*kl;qJ4UTXJn~MVM}0 zc&iy2wr^)fO)}Yv${)rIC(aR3j-}un+3O1ZI-yvp|7#w{`GV0 z-}%dbk^jiV*1IBh@4tOrQLkU_%YWB9yT4*vn>B09zdGsKc+QLQ>hJq+eV=dKn)~R| z*Vva{Z`WPC_O0&gVP~^KUaQ<^zy6h)dlUQ}$2x&4B&pWu-US*8l%mef+LU zl+%_KQ;P1Lh<(4`{_^+rvd{jnD|>2`fBNZ$_41GJvfPku7Z(hgx$1p6?X-z@TRn8yAGDUxPu`!xIIwo&rW`v2g&Efy*6~{&V*Mj|EyC%H<*^%@dqX*Q_|`W?KGZof=lF*+&&31_exI6D zAjWcs*YEjX%eC9Z7`LZNocg*?uQRiXX&pS5K3 zk&5g6_E~K4=dH=jx9@b{`JMO9&@7U9x7-fL=dT;RBcDI7y+2hso+*b@@LkQpO5Nod z`qORX3g&W^^WL9Yv*CZ>{Y;a%V!xjm;d2fRUiFE#tad7t0DY8zOEgO@GZef`3X zpU+*NFF79JB;b2s&*>XWV*je|gT$Cbg1#CkFPnrf-new9e%GB;CXB3fAkGJpo=~D0 xDaOIf%5bC3x_ftXK>Ag*VM*dIHv_}}|H4`C&UuG$Y643j22WQ%mvv4FO#t951-JkJ literal 0 HcmV?d00001 diff --git a/image_gen.go b/image_gen.go new file mode 100644 index 0000000..35080a3 --- /dev/null +++ b/image_gen.go @@ -0,0 +1,134 @@ +package main + +import ( + "encoding/csv" + "image" + "image/color" + "image/png" + "log" + "os" + "path/filepath" + "strconv" +) + +func main() { + // Path to the CSV file + userProfile := os.Getenv("USERPROFILE") + filePath := filepath.Join(userProfile, "AlpacaBot", "Collision Data", "collision_data.csv") + + // Open the CSV file + file, err := os.Open(filePath) + if err != nil { + log.Fatalf("Failed to open file: %v", err) + } + defer file.Close() + + // Read the CSV file + reader := csv.NewReader(file) + records, err := reader.ReadAll() + if err != nil { + log.Fatalf("Failed to read file: %v", err) + } + + // Group records by plane + dataByPlane := make(map[string][][]string) + for _, record := range records[1:] { // Skip the header row + plane := record[1] + dataByPlane[plane] = append(dataByPlane[plane], record) + } + + for plane, records := range dataByPlane { + // Find the min and max x, y coordinates + minX, minY, maxX, maxY := 1<<31-1, 1<<31-1, 0, 0 + for _, record := range records { + x, err := strconv.Atoi(record[2]) + if err != nil { + continue + } + y, err := strconv.Atoi(record[3]) + if err != nil { + continue + } + if x < minX { + minX = x + } + if y < minY { + minY = y + } + if x > maxX { + maxX = x + } + if y > maxY { + maxY = y + } + } + + // Create an empty image + width, height := maxX-minX+1, maxY-minY+1 + img := image.NewRGBA(image.Rect(0, 0, width, height)) + + // Fill in the image with data + for _, record := range records { + x, err := strconv.Atoi(record[2]) + if err != nil { + continue + } + y, err := strconv.Atoi(record[3]) + if err != nil { + continue + } + flag, err := strconv.Atoi(record[4]) + if err != nil { + continue + } + + // Determine the color based on the flag value + var col color.Color + switch flag { + case 0: + col = color.RGBA{0, 255, 0, 255} + case 0xFFFFFF: + col = color.RGBA{255, 0, 0, 255} + case 0x1000000: + col = color.RGBA{0, 0, 255, 255} + case 0x100: + col = color.RGBA{255, 255, 0, 255} + case 0x20000: + col = color.RGBA{128, 0, 128, 255} + case 0x200000: + col = color.RGBA{255, 128, 0, 255} + case 0x2: + col = color.RGBA{0, 255, 255, 255} + case 0x8: + col = color.RGBA{255, 0, 255, 255} + case 0x20: + col = color.RGBA{128, 128, 0, 255} + case 0x80: + col = color.RGBA{128, 128, 128, 255} + case 0x4: + col = color.RGBA{0, 128, 0, 255} + case 0x10: + col = color.RGBA{128, 0, 0, 255} + case 0x40: + col = color.RGBA{0, 0, 128, 255} + case 0x1: + col = color.RGBA{0, 128, 128, 255} + default: + col = color.RGBA{0, 0, 0, 255} + } + + // Set the pixel in the image + img.Set(x-minX, height-(y-minY)-1, col) + } + + // Save the image to a file + outputFileName := "collision_map_plane_" + plane + ".png" + outputFile, err := os.Create(outputFileName) + if err != nil { + log.Fatalf("Failed to create output file: %v", err) + } + defer outputFile.Close() + + png.Encode(outputFile, img) + } +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..9d4309e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,247 @@ +#include +#include +#include +#include + +#include + +void Setup() { + ScriptInfo Info; + Info.Name = "Collision Cacher"; + Info.Description = "Caches collision data around the player."; + Info.Version = "1.00"; + Info.Category = "Magic"; + Info.Author = "Warren"; + Info.UID = "UID"; + Info.ForumPage = "forum.alpacabot.org"; + SetScriptInfo(Info); +} + +class region_key { +public: + std::int32_t region; + std::int32_t plane; + + region_key() = default; + + region_key(std::int32_t region, std::int32_t plane) + : region(region), plane(plane) {} + + bool operator==(const region_key& other) const { + return region == other.region && plane == other.plane; + } +}; + +class collision { +public: + Tile tile; + Pathfinding::COLLISION_FLAG flag; + + collision(const Tile& tile, Pathfinding::COLLISION_FLAG flag) : tile(tile), flag(flag) {} + + bool operator==(const collision& other) const { + return tile == other.tile && flag == other.flag; + } +}; + +namespace std { + template<> + struct hash { + std::size_t operator()(const region_key& key) const { + std::size_t h1 = std::hash()(key.region); + std::size_t h2 = std::hash()(key.plane); + return h1 ^ (h2 << 1); + } + }; + + template<> + struct hash { + std::size_t operator()(const Tile& tile) const { + std::size_t h1 = std::hash()(tile.X); + std::size_t h2 = std::hash()(tile.Y); + std::size_t h3 = std::hash()(tile.Plane); + return h1 ^ (h2 << 1) ^ (h3 << 2); + } + }; + + template<> + struct hash { + std::size_t operator()(const collision& collision) const { + std::size_t h1 = std::hash()(collision.tile); + std::size_t h2 = std::hash()(static_cast(collision.flag)); + return h1 ^ (h2 << 1); + } + }; +} + +std::unordered_map> cached_regions; + +void cache_current_region() { + const auto get_tile_region = [](const Tile& tile) { + return ((std::int32_t)(((tile.X >> 6) << 8) | (tile.Y >> 6))); + }; + + const auto to_world_tile = [](const Pathfinding::TileNode& node, std::int32_t client_x, std::int32_t client_y, std::int32_t client_plane) { + return Tile( + node.X + client_x, + node.Y + client_y, + client_plane + ); + }; + + Pathfinding::GenerateNodes(); + const std::int32_t client_x = Internal::GetClientX(); + const std::int32_t client_y = Internal::GetClientY(); + const std::int32_t client_plane = Internal::GetClientPlane(); + + for (const auto& nodes : Pathfinding::GetNodes()) { + for (const auto& node : nodes) { + const auto flag = node.Flag; + const auto world_tile = to_world_tile(node, client_x, client_y, client_plane); + + if ((flag & Pathfinding::UNINITIALIZED) || flag == Pathfinding::UNINITIALIZED) { + continue; + } + + if ((flag == Pathfinding::CLOSED)) { + continue; + } + + std::int32_t current_region = get_tile_region(world_tile); + + cached_regions[region_key(current_region, client_plane)].emplace(world_tile, static_cast(flag)); + } + } +} + +void paint() { + Paint::Clear(); + std::vector texts; + auto local_tile = Players::GetLocal().GetTile(); + for (const auto& [key, collision_data] : cached_regions) { + texts.emplace_back( + "(" + std::to_string(key.region) + ", " + std::to_string(key.plane) + "): " + std::to_string(collision_data.size()) + ); + + for (const auto& collision : collision_data) { + if (collision.tile.DistanceFrom(local_tile) > 12) + continue; + + if ((collision.flag & Pathfinding::BLOCKED) || (collision.flag & Pathfinding::OCCUPIED)) { + Paint::DrawTile(collision.tile, 255, 0, 0, 255); + } else if (collision.flag & Pathfinding::NORTH) { + Paint::DrawTile(collision.tile, 255, 0, 255, 255); + } else if (collision.flag & Pathfinding::EAST) { + Paint::DrawTile(collision.tile, 0, 255, 0, 255); + } else if (collision.flag & Pathfinding::SOUTH) { + Paint::DrawTile(collision.tile, 0, 0, 255, 255); + } else if (collision.flag & Pathfinding::WEST) { + Paint::DrawTile(collision.tile, 255, 165, 0, 255); + } + } + } + + Point p = Point(0, 5); + for (const auto& text : texts) { + p += Point(0, 20); + Paint::DrawString(text, p, 0, 255, 0, 255); + } + Paint::SwapBuffer(); +} + +void verify_and_clean() { + // verify each tile in a region actually belongs to it, if not, remove it + for (auto it = cached_regions.begin(); it != cached_regions.end();) { + const auto& [key, collision_data] = *it; + const auto get_tile_region = [](const Tile& tile) { + return ((std::int32_t)(((tile.X >> 6) << 8) | (tile.Y >> 6))); + }; + + for (const auto& collision : collision_data) { + if (get_tile_region(collision.tile) != key.region) { + it->second.erase(collision); + } + } + + if (it->second.empty()) { + it = cached_regions.erase(it); + } else { + ++it; + } + } +} + +void write_collision_data(std::ofstream& file) { + file << "region,plane,x,y,flag\n"; + verify_and_clean(); + for (const auto& [key, collision_data] : cached_regions) { + for (const auto& collision : collision_data) { + if (collision.flag == Pathfinding::OPEN) + continue; + + file << key.region << "," << key.plane << "," << collision.tile.X << "," << collision.tile.Y << "," << static_cast(collision.flag) << "\n"; + } + } +} + +void read_collision_data(std::ifstream& file) { + std::string line; + std::getline(file, line); // skip csv header + while (std::getline(file, line)) { + std::stringstream ss(line); + std::string token; + std::vector tokens; + while (std::getline(ss, token, ',')) { + tokens.emplace_back(token); + } + + const auto region = std::stoi(tokens[0]); + const auto plane = std::stoi(tokens[1]); + const auto x = std::stoi(tokens[2]); + const auto y = std::stoi(tokens[3]); + const auto flag = static_cast(std::stoi(tokens[4])); + + cached_regions[region_key(region, plane)].emplace(Tile(x, y, plane), flag); + } +} + +std::string data_url() { + char *userprofile = std::getenv("USERPROFILE"); + if (userprofile == nullptr) + return ""; + + return std::string(userprofile) + "\\AlpacaBot\\Collision Data\\collision_data.csv"; +} + +bool OnStart() { + SetLoopDelay(5); + + std::string path = data_url(); + std::ifstream file(path); + read_collision_data(file); + return true; +} + +bool Loop() { + cache_current_region(); + paint(); + return true; +} + +bool OnBreak() { + return true; +} + +void OnEnd() { + char *userprofile = std::getenv("USERPROFILE"); + if (userprofile == nullptr) + return; + + std::string path = data_url(); + if (!std::filesystem::exists(path)) { + std::filesystem::create_directories(std::string(userprofile) + "\\AlpacaBot\\Collision Data\\"); + } + + std::ofstream file(path); + write_collision_data(file); +} \ No newline at end of file