From 0962d7c79c03b98914f897d397c107809eaa81c3 Mon Sep 17 00:00:00 2001 From: Brandon Cornejo Date: Tue, 17 Feb 2026 19:06:49 -0600 Subject: [PATCH] db bookmark system and clickable links --- logs/features/dbbookmarksync.tin | 7 + src/db.tin | 226 +++++++++++++++++++++++++++---- 2 files changed, 205 insertions(+), 28 deletions(-) create mode 100644 logs/features/dbbookmarksync.tin diff --git a/logs/features/dbbookmarksync.tin b/logs/features/dbbookmarksync.tin new file mode 100644 index 0000000..f393085 --- /dev/null +++ b/logs/features/dbbookmarksync.tin @@ -0,0 +1,7 @@ +#CLASS {dbsync} OPEN + +#VARIABLE {bookmark_sync} +{ +} + +#CLASS {dbsync} CLOSE diff --git a/src/db.tin b/src/db.tin index 43bd2e7..34a1085 100644 --- a/src/db.tin +++ b/src/db.tin @@ -1,6 +1,8 @@ #CLASS {database} {kill}; #CLASS {database} {open}; + +#VARIABLE {dbbookmark_file} {logs/features/dbbookmarksync.tin}; #VARIABLE {map_id_names} { {1}{Ankh-Morpork} {2}{AM Assassins} @@ -113,17 +115,18 @@ {map_name}{$map_id_names[$gatherable_results[4]]} }; - #format {gatherable_display} {%c [%c%d%c]: %c%s%c found in %c%s%c,%c %s%c<099>} {Azure}{Cyan}{$gather_count}{Azure}{Green}{$gatherable_info[item_name]}{Azure}{Orange}{$gatherable_info[room_short]}{Azure}{Orange}{$gatherable_info[map_name]}{Azure}; - #echo {$gatherable_display}; + #showme { [@dbroute_link{$gather_count;$gather_count}]: @dbroute_link{$gather_count;$gatherable_info[item_name]} found in @dbroute_link{$gather_count;$gatherable_info[room_short]}, $gatherable_info[map_name]<099>}; #variable {last_query_list[$gather_count]} {$gatherable_info}; #math {gather_count} {$gather_count + 1}; - } + }; + #showme {Generate a walking path with "db route #" or *clicking* the number or name of one of the results above.}; + #showme {}; } { #format {gatherable_display} {%cQuery Result: %c%s%c was not found.<099>} {Azure}{Green}{%1}{Azure}; #echo {$gatherable_display}; - } -} + }; +}; #ALIAS {db npc {[^{}\n]+}{( \{([\w\s-]+)\})?}$} { #unvariable {npc_display} {search_term} {query}; @@ -164,12 +167,13 @@ {room_short}{$npc_results[4]} }; - #format {npc_display} {%c [%c%d%c]: %c%s%c found in %c%s%c,%c %s%c<099>} {Azure}{Cyan}{$npc_count}{Azure}{Green}{$npc_info[npc_name]}{Azure}{Orange}{$npc_info[room_short]}{Azure}{Orange}{$npc_info[map_name]}{Azure}; - #echo {$npc_display}; + #showme { [@dbroute_link{$npc_count;$npc_count}]: @dbroute_link{$npc_count;$npc_info[npc_name]} found in @dbroute_link{$npc_count;$npc_info[room_short]}, $npc_info[map_name]<099>}; #variable {last_query_list[$npc_count]} {$npc_info}; #math {npc_count} {$npc_count + 1}; - } + }; + #showme {Generate a walking path with "db route #" or *clicking* the number or name of one of the results above.}; + #showme {}; } { #format {npc_display} {%cQuery Result: %c%s%c was not found.<099>} {Azure}{Green}{%1}{Azure}; #echo {$npc_display}; @@ -216,12 +220,13 @@ {room_short}{$npcitem_results[5]} }; - #format {npcitem_display} {%c [%c%d%c]: %c%s%c found on %c%s%c in %c%s%c,%c %s%c<099>} {Azure}{Cyan}{$npcitem_count}{Azure}{Green}{$npcitem_info[item_name]}{Azure}{White}{$npcitem_info[npc_name]}{Azure}{Orange}{$npcitem_info[room_short]}{Azure}{Orange}{$npcitem_info[map_name]}{Azure}; - #echo {$npcitem_display}; + #showme { [@dbroute_link{$npcitem_count;$npcitem_count}]: @dbroute_link{$npcitem_count;$npcitem_info[item_name]} found on $npcitem_info[npc_name] in @dbroute_link{$npcitem_count;$npcitem_info[room_short]}, $npcitem_info[map_name]<099>}; #variable {last_query_list[$npcitem_count]} {$npcitem_info}; #math {npcitem_count} {$npcitem_count + 1}; - } + }; + #showme {Generate a walking path with "db route #" or *clicking* the number or name of one of the results above.}; + #showme {}; } { #format {npcitem_display} {%cQuery Result: %c%s%c was not found.<099>} {Azure}{Green}{%1}{Azure}; #echo {$npcitem_display}; @@ -268,12 +273,15 @@ {map_name}{$map_id_names[$item_results[5]]} }; - #format {item_display} {%c [%c%d%c]: %c%s%c (%c%s%c) found in %c%s%c,%c %s%c<099>} {Azure}{Cyan}{$item_count}{Azure}{Green}{$item_info[item_name]}{Azure}{Yellow}{$item_info[sale_price]}{Azure}{Orange}{$item_info[room_short]}{Azure}{Orange}{$item_info[map_name]}{Azure}; - #echo {$item_display}; + #nop #format {item_display} {%c [%c%d%c]: %c%s%c (%c%s%c) found in %c%s%c,%c %s%c<099>} {Azure}{Cyan}{$item_count}{Azure}{Green}{$item_info[item_name]}{Azure}{Yellow}{$item_info[sale_price]}{Azure}{Orange}{$item_info[room_short]}{Azure}{Orange}{$item_info[map_name]}{Azure}; + #nop #echo {$item_display}; + #showme { [@dbroute_link{$item_count;$item_count}]: @dbroute_link{$item_count;$item_info[item_name]} ($item_info[sale_price]) found in @dbroute_link{$item_count;$item_info[room_short]}, $item_info[map_name]<099>}; #variable {last_query_list[$item_count]} {$item_info}; #math {item_count} {$item_count + 1}; }; + #showme {Generate a walking path with "db route #" or *clicking* the number or name of one of the results above.}; + #showme {}; } { #format {item_display} {%cQuery Result: %c%s%c was not found.<099>} {Azure}{Green}{%1}{Azure}; #echo {$item_display}; @@ -319,12 +327,14 @@ {room_type}{$room_results[4]} }; - #format {room_display} {%c [%c%d%c]: %c%s%c (%c%s%c) found in %c%s%c<099>} {Azure}{Cyan}{$room_count}{Azure}{Green}{$room_info[room_short]}{Azure}{Yellow}{$room_info[room_type]}{Azure}{Orange}{$room_info[map_name]}{Azure}; - #echo {$room_display}; + #nop #format {room_display} {%c [%c%d%c]: %c%s%c (%c%s%c) found in %c%s%c<099>} {Azure}{Cyan}{$room_count}{Azure}{Green}{$room_info[room_short]}{Azure}{Yellow}{$room_info[room_type]}{Azure}{Orange}{$room_info[map_name]}{Azure}; + #showme { [@dbroute_link{$room_count;$room_count}]: @dbroute_link{$room_count;$room_info[room_short]} ($room_info[room_type]) found in $room_info[map_name]<099>}; #variable {last_query_list[$room_count]} {$room_info}; #math {room_count} {$room_count + 1}; - } + }; + #showme {Generate a walking path with "db route #" or *clicking* the number or name of one of the results above.}; + #showme {}; } { #format {room_display} {%cQuery Result: %c%s%c was not found.<099>} {Azure}{Green}{%1}{Azure}; #echo {$room_display}; @@ -356,7 +366,7 @@ #list {route_length} {create} {$route_length}; #list {route_length} {size} {route_length}; - #format {route_confirm} {[speedwalk] A route was found, type "%cspeedwalk" to fast travel. [%c%g steps]<099>} {Green}{Cyan}{$route_length}; + #format {route_confirm} {[speedwalk] A route was found, type "%c@dbspeedwalk_link{}" to fast travel. [%c%g steps]<099>} {Green}{Cyan}{$route_length}; #echo {$route_confirm}; } { #format {route_display} {[speedwalk] No previous query data found, try searching first.<099>}; @@ -366,11 +376,11 @@ #ALIAS {speedwalk} { #send {RuhsSpeedRun}; -} +}; #ALIAS {db routeto %1} { #var {target_room} {%1}; - #format {route_display} {[speedwalk] Generating speedwalk from current location to specified id %s.<099>} {%1}; + #format {route_display} {[speedwalk] Generating speedwalk from current location to specified room. %s<099>} {%1}; #echo {$route_display}; @@ -393,24 +403,184 @@ #list {route_length} {create} {$route_length}; #list {route_length} {size} {route_length}; - #format {route_confirm} {[speedwalk] A route was found, type %cspeedwalk to fast travel. [%c%g steps]<099>} {Green}{Cyan}{$route_length}; + #format {route_confirm} {[speedwalk] A route was found, type %c@dbspeedwalk_link{} to fast travel. [%c%g steps]<099>} {Green}{Cyan}{$route_length}; #echo {$route_confirm}; }; #ALIAS {^db$} { - #showme {[speedwalk] Try "db help" for usage instructions.<099>}; + #showme {[speedwalk] Try "db help" for usage instructions.<099>}; }; #ALIAS {db help} { #showme {[speedwalk] Speedwalk and Database Lookup Commands:<099>}; - #showme {\t<138>* "db room " - search for a room by name<099>}; - #showme {\t<138>* "db item " - search for an item in shops by name<099>}; - #showme {\t<138>* "db npc " - search for an NPC by name<099>}; - #showme {\t<138>* "db npcitem " - search for an item in NPC inventories by name<099>}; - #showme {\t<138>* "db gatherable " - search for a gatherable item by name<099>}; + #showme { <138>* "db room " - search for a room by name<099>}; + #showme { <138>* "db item " - search for an item in shops by name<099>}; + #showme { <138>* "db npc " - search for an NPC by name<099>}; + #showme { <138>* "db npcitem " - search for an item in NPC inventories by name<099>}; + #showme { <138>* "db gatherable " - search for a gatherable item by name<099>}; #showme {<099>}; - #showme {After searching with one of the above commands, find a route there with "db route #"<099>}; - #showme {Then type "speedwalk" to start moving.<099>}; + #showme {After searching with one of the above commands, find a route there with "db route <#>", where "<#>" is the row number shown in the results. You can then type "speedwalk" to start moving. Alternatively, mouse-click on a result to generate a route, then click "speedwalk" to begin moving.<099>}; + #showme {<099>}; + #showme {There's also a bookmark system for frequently used rooms, see "db bookmark help" for details.<099>}; + #showme {<099>}; + #showme {Tips:<099>}; + #showme { <138>* When searching, the "query" is case-sensitive.<099>}; + #showme { <138>* Searches may be filtered to certain maps by providing a second parameter like "\{map_name\}".<099>}; + #showme { <138>* Example, to find swords in the Ramtops, you could "db item sword \{ramtops\}".<099>}; + #showme { <138>* Valid map names include:<099>}; + #showme { <138>* am/ankh-morpork <138>* bp/bes pelargic<099>}; + #showme { <138>* djb/djelibeybi <138>* ephebe<099>}; + #showme { <138>* genua <138>* ramtops<099>}; + #showme { <138>* sto/sto plains <138>* sto-lat <099>}; +}; + +#nop *** BOOKMARK SYSTEM IMPLEMENTATION ***; +#ALIAS {^db bookmark help$} { + #showme {[speedwalk] Speedwalk Bookmark System Commands:<099>}; + #showme { <138>* "db bookmark add here" - add current location to bookmarks.<099>}; + #showme { <138>* "db bookmark list" - show a list of saved locations.<099>}; + #showme { <138>* "db bookmark remove <#>" - remove bookmark at index..<099>}; + #showme {<099>}; + #showme {Generate a route from your current location to a bookmark using "db bookmark route <#>" or mouse-clicking on a result from "db bookmark list". You can then click or type "speedwalk to start moving.<099>}; +}; + +#nop sync database speedwalk bookmarks from file on load; +#class {dbsync} {clear}; +#class {dbsync} {read} {$dbbookmark_file}; +#variable {db_bookmark_list} {$bookmark_sync}; +#class {dbsync} {kill}; + +#ALIAS {^db bookmark list$} { + #showme {[speedwalk] Speedwalk Saved Bookmarks:<099>}; + #list {db_bookmark_list} {size} {db_bookmark_size}; + #if {$db_bookmark_size > 0} { + #var {bookmark_count} {0}; + #foreach {$db_bookmark_list[%*]} {bookmark_result} { + #math {bookmark_list_index} {$bookmark_count + 1}; + #variable {bookmark_room_id} {$db_bookmark_list[$bookmark_list_index][id]}; + #showme { [@dbrouteto_link{$bookmark_room_id;$bookmark_count}]: Room "@dbrouteto_link{$bookmark_room_id;$bookmark_result[name]}" in $bookmark_result[map] ($bookmark_result[type]).<099>}; + #math {bookmark_count} {$bookmark_count + 1}; + }; + }; + #else { + #showme { No saved bookmarks found, add one with "db bookmark add here" or refer to "db bookmark help".<099>}; + }; +}; +#ALIAS {^db bookmark add here$} { + #nop first - are we at our bookmark capacity?; + #list {db_bookmark_list} {size} {db_bookmark_size}; + #if {$db_bookmark_size > 19} { + #showme {[speedwalk] Maximum allowed number of bookmarks already set, remove one first.<099>}; + #return; + }; + + #nop next - do we already have this place bookmarked?; + #foreach {$db_bookmark_list[%*]} {bookmark_result} { + #if {"$bookmark_result[id]" == "$GMCP[room][info][identifier]"} { + #showme {[speedwalk] This room is already bookmarked and entitled "$bookmark_result[name]".<099>}; + #return; + }; + }; + + #nop TODO if we decide to allow nicknames then need to check for duplicates there as well; + #nop TODO saving class to file each time we add/remove so it persists; + + #nop some places don't have a "name" (e.g. Medina or Shades), don't allow bookmarking those for now.; + #if {"$GMCP[room][info][name]" == ""} { + #showme {[speedwalk] This room is not able to be bookmarked.<099>}; + #return; + }; + + #nop go to the database to get a MapID to store; + #format {query} {SELECT room_id, map_id, room_short, room_type FROM rooms WHERE room_id = '%s' LIMIT 1;} {$GMCP[room][info][identifier]}; + #format {db_command} {sqlite3 -separator ";" src/quow.db "%s"} {$query}; + #script {room_query_result} {$db_command}; + #format {room_query_result} {$room_query_result[1]}; + #replace {room_query_result} {\\} {}; + #list {room_results} {create} {${room_query_result}}; + + #variable {room_info} { + {room_id}{$room_results[1]} + {map_name}{$map_id_names[$room_results[2]]} + {room_short}{$room_results[3]} + {room_type}{$room_results[4]} + }; + + #nop finally put the new bookmark in our list; + #list {db_bookmark_list} {add} {{ + {id}{$room_info[room_id]} + {name}{$room_info[room_short]} + {map}{$room_info[map_name]} + {type}{$room_info[room_type]} + }}; + #showme {[speedwalk] Added a new bookmark for "$GMCP[room][info][name]" in $room_info[map_name] ($room_info[room_type]).<099>}; + /writedbbookmarkstofile; +}; +#ALIAS {^db bookmark remove %d$} { + #math {bookmark_removal_index} {%1 + 1}; + + #nop is this index in valid range?; + #list {db_bookmark_list} {size} {db_bookmark_size}; + #if {$db_bookmark_size < $bookmark_removal_index} { + #showme {[speedwalk] No bookmark with number "%1" set, check "db bookmark list".<099>}; + #return; + }; + + #nop otherwise seems valid, so remove it; + #list {db_bookmark_list} {get} {$bookmark_removal_index} {removed_bookmark}; + #list {db_bookmark_list} {delete} {$bookmark_removal_index}; + #showme {[speedwalk] Removed an existing bookmark for "$removed_bookmark[name]" at index "$bookmark_removal_index".<099>}; + /writedbbookmarkstofile; +}; +#ALIAS {^db bookmark route %d$} { + #math {bookmark_route_index} {%1 + 1}; + + #nop is this index in valid range?; + #list {db_bookmark_list} {size} {db_bookmark_size}; + #if {$db_bookmark_size < $bookmark_route_index} { + #showme {[speedwalk] No bookmark with number "%1" set, check "db bookmark list".<099>}; + #return; + }; + + #nop otherwise seems valid, so lets route to it; + db routeto $db_bookmark_list[$bookmark_route_index][id]; +}; +#ALIAS {^/writedbbookmarkstofile} { + #class {dbsync} {clear}; + #class {dbsync} {open}; + #var {bookmark_sync} {$db_bookmark_list}; + #class {dbsync} {close}; + + #system {touch $dbbookmark_file}; + #class {dbsync} {write} {$dbbookmark_file}; +}; +#nop *** END BOOKMARK SYSTEM IMPLEMENTATION ***; + + +#nop ===[ Handle Events for Clickable Links... for the newbs ]===; +#nop handle DBROUTE click events; +#EVENT {PRESSED SECURE LINK DBROUTE MOUSE BUTTON ONE} { + db route %4; +}; +#EVENT {PRESSED SECURE LINK DBROUTETO MOUSE BUTTON ONE} { + db routeto %4; +}; +#nop handle SPEEDWALK click events; +#EVENT {PRESSED SECURE LINK DBSPEEDWALK MOUSE BUTTON ONE} { + speedwalk; +}; + +#nop ===[ Functions to generate the clickable links ]===; +#FUNCTION {dbroute_link} { + #nop %1 = query result index, %2 = text to display the link as; + #return {\e]68;2;DBROUTE;%1\a\e[4;24m%2\e[24m}; +}; +#FUNCTION {dbrouteto_link} { + #nop %1 = id to route to, %2 = text to display the link as; + #return {\e]68;2;DBROUTETO;%1\a\e[4;24m%2\e[24m}; +}; +#FUNCTION {dbspeedwalk_link} { + #return {\e]68;2;DBSPEEDWALK;;\a\e[4mspeedwalk\e[24m}; };