diff --git a/mdtconfig.json b/mdtconfig.json index 5940f7c..17572fc 100644 --- a/mdtconfig.json +++ b/mdtconfig.json @@ -25,7 +25,7 @@ ["imperial guard", "orange", 5, false], ["^(.+?) (tang|sung|mcsweeney|fang|hong) bodyguards{0,1}$", "orange", 4, true], ["^(.+?) (tang|sung|mcsweeney|fang|hong) noblem(en|an)$", "orange", 3, true], - ["^(.+?) (tang|sung|mcsweeney|fang|hong) captain$", "orange", 3, true], + ["^(tang|sung|mcsweeney|fang|hong) captain$", "orange", 3, true], ["Djelibeybi Highlights"], ["^(.+?) pries(t|ts|tess|tesses)$", "", 0, true], @@ -50,6 +50,9 @@ ["grflx worker", "", 3, false], ["grflx workleader", "", 3, false], - ["Valid colours: orange, "] + ["Ramtops Highlights"], + ["headless horse rider", "red", 8, false], + + ["Valid colours: orange, red"] ] } diff --git a/src/actions.tin b/src/actions.tin index 64f706f..7df86a5 100644 --- a/src/actions.tin +++ b/src/actions.tin @@ -47,6 +47,11 @@ #HIGHLIGHT {You take the diamond-tipped chisel from your roll of gemcutting tools and chip away %1} {bold red}; #HIGHLIGHT {You take the diamond-tipped chisel from your roll of gemcutting tools and, struggling with %1} {bold red}; +#NOP ==[Kick Consortium]== +#ACTION {^It is your turn to fight... enter the combat ring.$} { + #showme {\a}; +} + #NOP ==[End Session On Quit]== #ACTION {Thanks for playing. See you next time.} { diff --git a/src/gmcp.tin b/src/gmcp.tin index c76e2bf..14b963a 100644 --- a/src/gmcp.tin +++ b/src/gmcp.tin @@ -28,9 +28,17 @@ #math {hploss} {$GMCP[vitals][hp] - $GMCP[oldvitals][hp]}; #if {$hploss < -150} { - #echo {<139>HP IS FALLING! CAREFUL!<099>}; + #format {hp_loss_display} {<139>HP IS FALLING! CAREFUL! (Lost %s HP)<099>} {$hploss}; + #echo {$hp_loss_display}; #showme {\a\a}; } + + #math {xpgain} {$GMCP[vitals][xp] - $GMCP[oldvitals][xp]}; + #if {$xpgain > 5000} { + #format {xp_gain_display} {<179>(+%g XP)<099>} {$xpgain}; + + #echo {$xp_gain_display}; + } update_prompt; } @@ -45,7 +53,9 @@ { #IF {$debug} { #SHOWME %1 }; #VAR GMCP[room][info] {%0}; - #nop; + + /spottimercheckroomid $GMCP[room][info][identifier] + #nop Run our spot timer logic against new identifier } #EVENT {IAC SB GMCP room.map IAC SE} @@ -70,11 +80,13 @@ #EVENT {IAC WILL GMCP} { - #SHOWME {GMCP ENABLED}; #SEND {$IAC$DO$GMCP\}; #nop #SEND {$IAC$SB$GMCP Core.Hello { "client": "$CLIENT_NAME", "version": "$CLIENT_VERSION" } $IAC$SE\}; - #SEND {$IAC$SB$GMCP Core.Hello { "client": "TinTin++", "version": "2.01.2" } $IAC$SE\}; - #SEND {$IAC$SB$GMCP Core.Supports.Set ["Char.Vitals", "room.info", "room.map", "room.writtenmap", "char.info"] $IAC$SE\} + #nop #SEND {$IAC$SB$GMCP Core.Hello { "client": "TinTin++", "version": "2.01.2" } $IAC$SE\}; + #nop #SEND {$IAC$SB$GMCP Core.Supports.Set ["Char.Vitals", "char.info", "char.login", "room.info", "room.map", "room.writtenmap"] $IAC$SE\} + #SEND {$IAC$SB$GMCP core.hello { "client" : "TinTin++", "version" : "2.01.2" } $IAC$SE\}; + #SEND {$IAC$SB$GMCP core.supports.set [ "char.login", "char.info", "char.vitals", "room.info", "room.map", "room.writtenmap" ] $IAC$SE\}; + #nop; } #EVENT {PROGRAM START} diff --git a/src/maproute.py b/src/maproute.py new file mode 100644 index 0000000..a3454f8 --- /dev/null +++ b/src/maproute.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python + +import sys +import sqlite3 + +class MapRoute: + def __init__(self): + self.locations_by_room_id = {} + self.exits_by_id = {} + self.exits_by_exit = {} + + self.return_alias = None + + self.db = self.database_connect() + self.load_locations() + self.load_exits() + + def database_connect(self): + con = sqlite3.connect('src/quow.db') + con.row_factory = sqlite3.Row + return con + + def load_locations(self): + cur = self.db.cursor() + cur.execute("SELECT room_id, map_id, xpos, ypos, room_short, room_type FROM rooms") + for row in cur.fetchall(): + self.locations_by_room_id[row[0]] = [row[1], row[2], row[3], row[4], row[5]] + self.exits_by_id[row['room_id']] = {} + self.exits_by_exit[row['room_id']] = {} + + def load_exits(self): + cur = self.db.cursor() + cur.execute("SELECT room_id, connect_id, exit FROM room_exits") + for row in cur.fetchall(): + if self.exits_by_id.get(row['room_id']) is not None and self.exits_by_id.get(row['connect_id']) is not None: + self.exits_by_id[row['room_id']][row['connect_id']] = row['exit'] + self.exits_by_exit[row['room_id']][row['exit']] = row['connect_id'] + + def route_to_room(self, current_id, target_id, same_place): + # If we can't match one of the room identifiers, back out + if not current_id or not target_id or not self.locations_by_room_id.get(target_id) or not self.locations_by_room_id.get(current_id): + return + + sDoPath, sFinalDestination, iResults = self.route_find( + current_id, target_id, + self.locations_by_room_id[target_id][0], + self.locations_by_room_id[target_id][1], + self.locations_by_room_id[target_id][2], + same_place + ) + + if sDoPath != "": + sDoPath = "alias RuhsSpeedRun {}".format(sDoPath) + if len(sDoPath) > 1700: + pass + else: + self.return_alias = sDoPath + + def route_find(self, start_id, dest_id, dest_map, dest_x, dest_y, same_place=True): + sDoRoom = [start_id] + bEverDone = {start_id: True} + sIDToRoomNum = {start_id: 1} + iGotHereFrom = {} + iNextRoom = 1 + iTotalRooms = 1 + sLinkedTo = [] + iSearchDepth = 0 + bDone = False + iFinalRoom = 0 + iPreviousTotal = 0 + + # "Infinite" loop + while bDone == False: + # Loop through all the rooms we have yet to do + iPreviousTotal = iTotalRooms + for iN in xrange(iNextRoom - 1, iPreviousTotal): + # Loop through all exits from this room + for sKey, sExitData in self.exits_by_id[sDoRoom[iN]].iteritems(): + # Make sure we aren't looping back around on ourselves, and that we haven't already finished + if sKey != start_id and bEverDone.get(sKey) == None and iFinalRoom == 0: + iTotalRooms = iTotalRooms + 1 + # Add THIS destination of THIS room to the "to-be-processed" list + sDoRoom.append(sKey) + # Flag this room so we never come here again + bEverDone[sKey] = True + # Record ID to room-num + sIDToRoomNum[sKey] = iTotalRooms + # Record back-tracking data + iGotHereFrom[iTotalRooms] = [sIDToRoomNum[sDoRoom[iN]], sExitData] + # See if we made it yet + if sDoRoom[iN] == dest_id: + bDone = True + iFinalRoom = iN + elif sKey == dest_id: + bDone = True + iFinalRoom = iTotalRooms + elif (same_place == True and self.locations_by_room_id[sDoRoom[iN]][0] == dest_map + and self.locations_by_room_id[sDoRoom[iN]][1] == dest_x + and self.locations_by_room_id[sDoRoom[iN]][2] == dest_y): + # Maybe we reached the co-ordinates instead - eg a house with multiple rooms in one pixels -- only stop here if we didn't START here + if (self.locations_by_room_id[start_id][0] != dest_map or + self.locations_by_room_id[start_id][1] != dest_x or + self.locations_by_room_id[start_id][2] != dest_y): + bDone = True + iFinalRoom = iN + # elif + # not back to beginning + # loop through exit rooms + # loop through "to-do" + + iNextRoom = iPreviousTotal + 1 + if iNextRoom > iTotalRooms: + # Failed to find a route + bDone = True + iSearchDepth = iSearchDepth + 1 + if iSearchDepth > 500: + # Failed, too deep + bDone = True + iFinalRoom = 0 + break + # infinite loop end + + # Did we actually find a room? + if iFinalRoom != 0: + sPath = [] + bDone = False + iCurRoom = iFinalRoom + while bDone == False: + sPath.append(iGotHereFrom[iCurRoom][1]) + iCurRoom = iGotHereFrom[iCurRoom][0] + if iCurRoom == 1: + bDone = True + sRealPath = "" + for iN in xrange(len(sPath), 0, -1): + if sRealPath != "": + sRealPath = "{};".format(sRealPath) + sRealPath = "{}{}".format(sRealPath, sPath[iN-1]) + return sRealPath, sDoRoom[iFinalRoom-1], len(sPath) + # Didn't find a route, return blanks + return "", "", 0 + + +if __name__ == '__main__': + if len(sys.argv) < 2: + print('[error] No input provided.') + sys.exit() + + current_room, target_room = sys.argv.pop(1), sys.argv.pop(1) + + router = MapRoute() + router.route_to_room(current_room, target_room, True) + # TODO: Can we determine samePlace? We need to compare the MapID of current_room and target_room when found? + # d route between df6506b79c67080920fccbf27ce0d06cd392e01a and 03360211b315daf089d9ba329dd32417b9c7f54c. + + if router.return_alias: + print(router.return_alias) + else: + print(0) diff --git a/src/quow.tin b/src/quow.tin index b6634e1..5aa4f48 100644 --- a/src/quow.tin +++ b/src/quow.tin @@ -60,16 +60,25 @@ {57}{Skund Wolf Trail} } +#LIST {last_query_list} {create}; + #ALIAS {db gatherable %1} { #unvariable {gatherable_display}; - #format {query} {SELECT item_name, room_short, map_id, INSTR(item_name, '%s') pos FROM shop_items INNER JOIN rooms on rooms.room_id = shop_items.room_id WHERE pos > 0 AND sale_price = 'gather';} {%1}; + #format {query} {SELECT item_name, room_short, shop_items.room_id, map_id, INSTR(item_name, '%s') pos FROM shop_items INNER JOIN rooms on rooms.room_id = shop_items.room_id WHERE pos > 0 AND sale_price = 'gather';} {%1}; #format {db_command} {sqlite3 -separator ";" src/quow.db "%s"} {$query}; #script {gatherable_query_result} {$db_command}; #list {gatherable_query_result} {size} {gatherable_result_size}; + #list {last_query_list} {clear}; + #if {$gatherable_result_size > 0} { + #format {gatherable_display} {%cResults for gatherables matching %c"%c%s%c"%c.} {bold blue}{green}{yellow}{%1}{green}{bold blue}; + #echo {$gatherable_display}; + + #var {gather_count} {0}; + #foreach {$gatherable_query_result[%*]} {inner_query_result} { #replace {inner_query_result} {\\} {}; #list gatherable_results create {${inner_query_result}}; @@ -77,11 +86,15 @@ #variable {gatherable_info} { {item_name}{$gatherable_results[1]} {room_short}{$gatherable_results[2]} - {map_name}{$map_id_names[$gatherable_results[3]]} + {room_id}{$gatherable_results[3]} + {map_name}{$map_id_names[$gatherable_results[4]]} }; - #format {gatherable_display} {%cQuery Result: %c%s%c found in %c%s, %s%c} {bold blue}{green}{$gatherable_info[item_name]}{bold blue}{orange}{$gatherable_info[room_short]}{$gatherable_info[map_name]}{bold blue}; + #format {gatherable_display} {%c [%c%d%c]: %c%s%c found in %c%s%c,%c %s%c} {bold blue}{cyan}{$gather_count}{bold blue}{green}{$gatherable_info[item_name]}{bold blue}{orange}{$gatherable_info[room_short]}{bold blue}{orange}{$gatherable_info[map_name]}{bold blue}; #echo {$gatherable_display}; + + #variable {last_query_list[$gather_count]} {$gatherable_info}; + #math {gather_count} {$gather_count + 1}; } } { #format {gatherable_display} {%cQuery Result: %c%s%c was not found.} {bold blue}{green}{%1}{bold blue}; @@ -89,35 +102,158 @@ } } -#ALIAS {db buyable %1} { - #unvariable {buyable_display}; +#ALIAS {db npc %1} { + #unvariable {npc_display}; + + #format {query} {SELECT npc_name, rooms.map_id, rooms.room_id, rooms.room_short, INSTR(npc_name, '%s') pos FROM npc_info INNER JOIN rooms on rooms.room_id = npc_info.room_id WHERE pos > 0 LIMIT 10} {%1}; + #format {db_command} {sqlite3 -separator ";" src/quow.db "%s"} {$query}; + + #script {npc_query_result} {$db_command}; + #list {npc_query_result} {size} {npc_result_size}; + + #list {last_query_list} {clear}; + + #if {$npc_result_size > 0} { + #format {npc_display} {%cResults for NPCs matching %c"%c%s%c"%c.} {bold blue}{green}{yellow}{%1}{green}{bold blue}; + #echo {$npc_display}; + + #var {npc_count} {0}; + + #foreach {$npc_query_result[%*]} {inner_query_result} { + #replace {inner_query_result} {\\} {}; + #list npc_results create {${inner_query_result}}; + + #variable {npc_info} { + {npc_name}{$npc_results[1]} + {map_name}{$map_id_names[$npc_results[2]]} + {room_id}{$npc_results[3]} + {room_short}{$npc_results[4]} + }; + + #format {npc_display} {%c [%c%d%c]: %c%s%c found in %c%s%c,%c %s%c} {bold blue}{cyan}{$npc_count}{bold blue} + {green}{$npc_info[npc_name]}{bold blue}{orange}{$npc_info[room_short]}{bold blue}{orange}{$npc_info[map_name]}{bold blue}; + #echo {$npc_display}; + + #variable {last_query_list[$npc_count]} {$npc_info}; + #math {npc_count} {$npc_count + 1}; + } + } { + #format {npc_display} {%cQuery Result: %c%s%c was not found.} {bold blue}{green}{%1}{bold blue}; + #echo {$npc_display}; + } +}; + +#ALIAS {db item %1} { + #unvariable {item_display}; + + #format {query} {SELECT item_name, sale_price, room_short, shop_items.room_id, map_id, INSTR(item_name, '%s') pos FROM shop_items INNER JOIN rooms on rooms.room_id = shop_items.room_id WHERE pos > 0 AND sale_price != 'gather' LIMIT 10;} {%1}; + #format {db_command} {sqlite3 -separator ";" src/quow.db "%s"} {$query}; + + #script {item_query_result} {$db_command}; + #list {item_query_result} {size} {item_result_size}; + + #list {last_query_list} {clear}; + + #if {$item_result_size > 0} { + #format {item_display} {%cResults for items matching %c"%c%s%c"%c.} {bold blue}{green}{yellow}{%1}{green}{bold blue}; + #echo {$item_display}; + + #var {item_count} {0}; + + #foreach {$item_query_result[%*]} {inner_query_result} { + #replace {inner_query_result} {\\} {}; + #list item_results create {${inner_query_result}}; + + #variable {item_info} { + {item_name}{$item_results[1]} + {sale_price}{$item_results[2]} + {room_short}{$item_results[3]} + {room_id}{$item_results[4]} + {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} {bold blue}{cyan}{$item_count}{bold blue}{green}{$item_info[item_name]}{bold blue}{yellow}{$item_info[sale_price]}{bold blue}{orange}{$item_info[room_short]}{bold blue}{orange}{$item_info[map_name]}{bold blue}; + #echo {$item_display}; + + #variable {last_query_list[$item_count]} {$item_info}; + #math {item_count} {$item_count + 1}; + } + } { + #format {item_display} {%cQuery Result: %c%s%c was not found.} {bold blue}{green}{%1}{bold blue}; + #echo {$item_display}; + } +} + +#ALIAS {db room %1} { + #unvariable {room_display}; - #format {query} {SELECT item_name, sale_price, room_short, map_id, INSTR(item_name, '%s') pos FROM shop_items INNER JOIN rooms on rooms.room_id = shop_items.room_id WHERE pos > 0 AND sale_price != 'gather' LIMIT 10;} {%1}; + #format {query} {SELECT room_id, map_id, room_short, room_type, INSTR(room_short, '%s') pos FROM rooms WHERE pos > 0 LIMIT 10;} {%1}; #format {db_command} {sqlite3 -separator ";" src/quow.db "%s"} {$query}; - #script {buyable_query_result} {$db_command}; - #echo {RESULT: $buyable_query_result}; - #list {buyable_query_result} {size} {buyable_result_size}; + #script {room_query_result} {$db_command}; + #list {room_query_result} {size} {room_result_size}; + + #list {last_query_list} {clear}; + + #if {$room_result_size > 0} { + #format {room_display} {%cResults for rooms matching %c"%c%s%c"%c.} {bold blue}{green}{yellow}{%1}{green}{bold blue}; + #echo {$room_display}; - #if {$buyable_result_size > 0} { - #foreach {$buyable_query_result[%*]} {inner_query_result} { + #var {room_count} {0}; + + #foreach {$room_query_result[%*]} {inner_query_result} { #replace {inner_query_result} {\\} {}; - #list buyable_results create {${inner_query_result}}; + #list room_results create {${inner_query_result}}; - #variable {buyable_info} { - {item_name}{$buyable_results[1]} - {sale_price}{$buyable_results[2]} - {room_short}{$buyable_results[3]} - {map_name}{$map_id_names[$buyable_results[4]]} + #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]} }; - #format {buyable_display} {%cQuery Result: %c%s%c (%c%s%c) found in %c%s, %s%c} {bold blue}{green}{$buyable_info[item_name]}{bold blue}{yellow}{$buyable_info[sale_price]}{bold blue}{orange}{$buyable_info[room_short]}{$buyable_info[map_name]}{bold blue}; - #echo {$buyable_display}; + #format {room_display} {%c [%c%d%c]: %c%s%c (%c%s%c) found in %c%s%c} {bold blue}{cyan}{$room_count}{bold blue}{green}{$room_info[room_short]}{bold blue}{yellow}{$room_info[room_type]}{bold blue}{orange}{$room_info[map_name]}{bold blue}; + #echo {$room_display}; + + #variable {last_query_list[$room_count]} {$room_info}; + #math {room_count} {$room_count + 1}; + } + } { + #format {room_display} {%cQuery Result: %c%s%c was not found.} {bold blue}{green}{%1}{bold blue}; + #echo {$room_display}; + }; +}; + +#ALIAS {db route %1} { + #if {&last_query_list[%1]} { + #var {target_room} {$last_query_list[%1]}; + #format {route_display} {%c[speedwalk] Generating speedwalk from current location to %c%s%c, %c%s%c...} {bold blue}{green}{$target_room[room_short]}{bold blue}{orange}{$target_room[map_name]}{bold blue}; + + #echo {$route_display}; + + #var {route_current_room_id} {$GMCP[room][info][identifier]}; + #var {route_target_room_id} {$target_room[room_id]}; + + #format {route_command} {python src/maproute.py %s %s} {$route_current_room_id} {$route_target_room_id}; + #script {speedwalk_result} {$route_command}; + + #if {$speedwalk_result[1] = 0} { + #format {route_error} {%c[speedwalk] Unable to find route to %c%s%c or unknown current room.} {bold blue}{green}{$target_room[room_short]}{bold blue}; + #echo {$route_error}; + #return; } + #send {$speedwalk_result[1]}; + + #format {route_confirm} {%c[speedwalk] A route was found, type "%cspeedwalk%c" to fast travel.} {bold blue}{green}{bold blue}; + #echo {$route_confirm}; } { - #format {buyable_display} {%cQuery Result: %c%s%c was not found.} {bold blue}{green}{%1}{bold blue}; - #echo {$buyable_display}; + #format {route_display} {%c[speedwalk] No previous query data found, try searching first.} {bold blue}; + #echo {$route_display}; } +}; + +#ALIAS {speedwalk} { + #send {RuhsSpeedRun}; } #CLASS {quow} {close}; diff --git a/src/spottimers.tin b/src/spottimers.tin index cce79a9..bcce4c0 100644 --- a/src/spottimers.tin +++ b/src/spottimers.tin @@ -283,11 +283,11 @@ #send {$sync_message}; } -#EVENT {IAC SB GMCP room.info IAC SE} -{ - #var {room_info} {%0}; +#nop #EVENT {IAC SB GMCP room.info IAC SE} +#ALIAS {/spottimercheckroomid %1} { + #var {room_info} {%1}; #foreach {$visittimers[]} {spot} { - #regex {$room_info[identifier]} {$spot} { + #regex {$room_info} {$spot} { #format {visittimers[$spot]} {%T}; } }