Skip to content

Instantly share code, notes, and snippets.

@binaryatrocity
Last active December 26, 2017 19:44
Show Gist options
  • Save binaryatrocity/80d60a3f3245bbae7c4c32cc2fc5e00b to your computer and use it in GitHub Desktop.
Save binaryatrocity/80d60a3f3245bbae7c4c32cc2fc5e00b to your computer and use it in GitHub Desktop.
Add verbose/brief combat toggle to quows minimap
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Graphical minimap and location GPS created by Quow-->
<muclient>
<plugin
name="CowBar"
author="Quow"
id="bfe35205f026786ea1d56e3b"
language="Lua"
purpose="Minimap, UI &amp; More!"
date_written="2016-08-27"
date_modified="2017-11-20"
save_state="y"
requires="4.84"
version="2.13"
>
</plugin>
<script>
<![CDATA[
-- *******************************************************************************
-- ***** Minimap, Map-Tracker and Custom UI made by Quow *****
-- *******************************************************************************
-- STOP!
-- *********************************************
-- ***** DO NOT EDIT ANYTHING IN THIS FILE! ****
-- *********************************************
-- Unless you are an advanced user looking to specifically edit parts of the plugin code, please do not edit anything past this point
-- All user-configurable data should be done from within the menus and commands this plugin provides in Mushclient
-- You should not need to edit anything below this point - you can resize the windows, and set other options, in-client
-- Check "help minimap". Right-click the windows for other options. Left-click drag to move windows around. Drag the bottom/side edges of windows to resize them.
-- *********************************************
-- ***** DO NOT EDIT ANYTHING IN THIS FILE! ****
-- *********************************************
-- *************************************
-- ***** Preset Global colour codes ****
-- *************************************
-- Well, if you REALLY want to edit anything, these colours are pretty safe to edit if you want!
sGlobalColourBlack = "black"
sGlobalColourSilver = "silver"
sGlobalColourOrange = "darkorange"
sGlobalColourCyan = "cyan"
sGlobalColourWhite = "white"
sGlobalColourGreen = "yellowgreen"
sGlobalColourRed = "#BC0000"
sGlobalColourGrey = "gray"
-- But only change the colours above, not below!
iGlobalColourWhite = ColourNameToRGB(sGlobalColourWhite)
iGlobalColourGreen = ColourNameToRGB(sGlobalColourGreen)
iGlobalColourRed = ColourNameToRGB(sGlobalColourRed)
iGlobalColourSilver = ColourNameToRGB(sGlobalColourSilver)
iGlobalColourOrange = ColourNameToRGB(sGlobalColourOrange)
iGlobalColourBlack = ColourNameToRGB(sGlobalColourBlack)
iGlobalColourGrey = ColourNameToRGB(sGlobalColourGrey)
-- Grab Mushclient version to check for feature capabilities
iMushclientVersion = tonumber(GetInfo(72))
-- Windows store-file location:
-- C:\Users\<your username>\AppData\Local\VirtualStore\Program Files (x86)\MUSHclient\worlds\plugins\state\
-- *************************************
-- ***** Desired GMCP Data Requested ***
-- *************************************
-- GMCP Character stats request
bRequestCharVitals = true
if (GetVariable("bRequestCharVitals") == "false") then
bRequestCharVitals = false
end
-- NOTE: If you want your own plugins to received MXP character vitals, either set the above to false and reconnect, OR:
-- Use the "OnPluginBroadcast" feature in your own plugin and you can tap into the GMCP Char.Vitals sent by this plugin instead
-- GMCP Written-Room-Map request
bRequestWrittenMap = true
if (GetVariable("bRequestWrittenMap") == "false") then
bRequestWrittenMap = false
end
-- GMCP Room-ASCII-Map request
bRequestRoomMap = true
if (GetVariable("bRequestRoomMap") == "false") then
-- Commented out as v2.06+ *NEEDS* this for ascii map to read properly
--bRequestRoomMap = false
end
-- You do NOT need to set the map path any more!
sQuowMapPath = ""
if (GetVariable("sQuowMapPath") ~= nil) then
sQuowMapPath = GetVariable("sQuowMapPath")
end
-- You do NOT need to set the map path any more!
-- *******************************************************
-- * Check for automatic \maps\ path in plugin location: *
-- *******************************************************
if (sQuowMapPath == "") then
sQuowMapPath = (GetPluginInfo(GetPluginID(), 20)) .. "maps\\"
end
Note("")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar Notice:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Plugin loading. Your \\maps\\ folder is being looked for in this location:")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "\"")
ColourTell(sGlobalColourCyan, sGlobalColourBlack, sQuowMapPath)
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "\"")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Ensure this is where your maps folder is, if not please correct and reload the plugin!")
Note("")
-- *************************************************
-- * Check if the user has aliases enabled or not: *
-- *************************************************
if (GetCurrentValue("enable_aliases") ~= 1) then
SetOption ("enable_aliases", 1)
Note("")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar Notice:")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your aliases in MUSHclient were disabled.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Aliases are needed to use the 'minimap' command, or 'help minimap', added by the plugin.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "The plugin has enabled aliases in your MUSHclient world settings for you, you do not need to do anything!")
Note("")
end
-- ************************************************
-- * Check if the user has timers enabled or not: *
-- ************************************************
if (GetCurrentValue("enable_timers") ~= 1) then
SetOption ("enable_timers", 1)
Note("")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar Notice:")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your timers in MUSHclient were disabled.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Timers are needed for the XP/hour rate and graphs, GP regen prediction, Disc game date auto updating, and other features.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "The plugin has enabled timers in your MUSHclient world settings for you, you do not need to do anything!")
Note("")
end
-- **************************************************
-- * Check if the user has Mushclient 4.99/5.00 *
-- **************************************************
if (iMushclientVersion == 4.99 or iMushclientVersion == 5) then
Note("")
ColourNote("red", sGlobalColourBlack, "===== Quow's Cow Bar Fatal Error =====")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You are running MUSHclient 4.99 or 5.00!")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "MUSHclient 4.99 and 5.00 have a fatal bug in some of their core functions, which prevents Quow's Cow Bar from working!")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Any other version from 4.84 up to 5.03+ should work fine. Please download a different version from:")
ColourNote(sGlobalColourCyan, sGlobalColourBlack, "http://www.gammon.com.au/files/mushclient/?M=D")
ColourNote("red", sGlobalColourBlack, "===== Quow's Cow Bar Fatal Error =====")
Note("")
end
-- Require JSON, we use it a few times!
require "json"
-- "Ongoing" version, used for running developments, database updates for the user, etc.
sPluginFullVersion = tostring(GetPluginInfo("bfe35205f026786ea1d56e3b", 19)) -- .. "_a"
-- Prepare plugin variables
winMinimap = GetPluginID() .. "minimap"
winInfoMinimap = ""
winMDT = GetPluginID() .. "mdt"
winInfoMDT = ""
winBars = GetPluginID() .. "bars"
winInfoBars = ""
winStats = GetPluginID() .. "stats"
winInfoStats = ""
winXP = GetPluginID() .. "xp"
winInfoXP = ""
winShields = GetPluginID() .. "shields"
winInfoShields = ""
winComms = GetPluginID() .. "comms"
winInfoComms = ""
winAscii = GetPluginID() .. "ascii"
winInfoAscii = ""
-- Get chat window filter options
objChatFilters = {}
iChatExtraChannels = 0
iCurrentChannelChoice = tonumber(GetVariable("iCurrentChannelChoice"))
if (iCurrentChannelChoice == nil) then
iCurrentChannelChoice = 1
end
if (GetVariable("objChatFilters") ~= nil) then
objChatFilters = json.decode(GetVariable("objChatFilters"))
else
objChatFilters = {
["Tells_In"] = {true, true, false},
["Tells_Out"] = {true, true, false},
["Group_Say"] = {true, true, false},
["One"] = {true, true, false},
["newbie"] = {true, true, false},
["cre"] = {true, true, false},
["special"] = {true, true, false},
}
end
-- And the user tabs
objChatTabs = {}
if (GetVariable("objChatTabs") ~= nil) then
objChatTabs = json.decode(GetVariable("objChatTabs"))
else
objChatTabs = {
[1] = {"All", {"*All*"}},
[2] = {"Tells", {"Tells_In", "Tells_Out"}},
[3] = {"Group", {"Group_Say"}},
[4] = {"Talkers", {"*Talkers*"}},
[5] = {"One", {"One"}},
}
end
iCommsMessagesCurrentlyShown = 0
iCommsCountByType = {}
for sKey, sData in pairs(objChatFilters) do
iCommsCountByType[sKey] = 0
iChatExtraChannels = iChatExtraChannels + 1
end
-- Get all the window size data decompiled
WINDATA = {}
if (GetVariable("WINDATA") ~= nil) then
WINDATA = json.decode(GetVariable("WINDATA"))
end
iThemeLayoutLocked = tonumber(GetVariable("iThemeLayoutLocked"))
if (iThemeLayoutLocked == nil) then
iThemeLayoutLocked = 0
end
-- Set default values for core/primary windows
if (WINDATA[winMinimap] == nil) then
WINDATA[winMinimap] = {["WIDTH"] = 250, ["HEIGHT"] = 250, ["SHOW"] = true, ["LOCKED"] = false}
end
if (WINDATA[winMDT] == nil) then
WINDATA[winMDT] = {["WIDTH"] = 400, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false}
end
if (WINDATA[winBars] == nil) then
WINDATA[winBars] = {["WIDTH"] = 190, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false}
end
if (WINDATA[winStats] == nil) then
WINDATA[winStats] = {["WIDTH"] = 190, ["HEIGHT"] = 220, ["SHOW"] = true, ["LOCKED"] = false}
end
if (WINDATA[winXP] == nil) then
WINDATA[winXP] = {["WIDTH"] = 190, ["HEIGHT"] = 180, ["SHOW"] = true, ["LOCKED"] = false}
end
if (WINDATA[winShields] == nil) then
WINDATA[winShields] = {["WIDTH"] = 190, ["HEIGHT"] = 180, ["SHOW"] = true, ["LOCKED"] = false}
end
if (WINDATA[winComms] == nil) then
WINDATA[winComms] = {["WIDTH"] = 400, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false}
end
if (WINDATA[winAscii] == nil) then
WINDATA[winAscii] = {["WIDTH"] = 80, ["HEIGHT"] = 80, ["SHOW"] = true, ["LOCKED"] = false}
end
-- Error checking for corruption
bWindowErrors = false
sFatalErrorList = ""
for iKey, sData in pairs(WINDATA) do
if (sData["WIDTH"] < 5) then
WINDATA[iKey]["WIDTH"] = 50
bWindowErrors = true
sFatalErrorList = sFatalErrorList .. tostring(iKey) .. "-W,"
end
if (sData["HEIGHT"] < 5) then
WINDATA[iKey]["HEIGHT"] = 50
bWindowErrors = true
sFatalErrorList = sFatalErrorList .. tostring(iKey) .. "-H,"
end
end
if (bWindowErrors == true) then
Note("At least one window had a corrupted size of below 5, and has been reset by the CowBar to prevent fatal errors [" .. sFatalErrorList .. "]")
Note("You can reset all miniwindows back to default positions with 'minimap reset', or by choosing an 'Instant Layout' in right click menus.")
end
-- Pre-prepped measurements for speed
MINIMAP_WIDTH=0
MINIMAP_HEIGHT=0
MINIMAP_X=0
MINIMAP_Y=0
MINIMAP_CX=0
MINIMAP_CY=0
-- Character vitals array, with default values instead of allowing "nil"s on initialisation
iCharVitals = {["maxgp"] = -1, ["burden"] = -1, ["gp"] = -1, ["maxhp"] = -1, ["xp"] = 0, ["hp"] = -1}
iCharOldVitals = {["maxgp"] = -1, ["burden"] = -1, ["gp"] = -1, ["maxhp"] = -1, ["xp"] = 0, ["hp"] = -1}
-- Shields and group data
sMyPlayerName = GetVariable("sMyPlayerName")
if (sMyPlayerName == nil) then
sMyPlayerName = ""
end
iTotalGroupMembers = 1
sGroupMembers = {
["You"] = {["HP"] = 0, ["GP"] = 0, ["TPA"] = 0, ["CCC"] = 0, ["EFF"] = 0, ["KII"] = 0, ["MS"] = 0, ["MemberSince"] = 0, ["Kills"] = 0, },
}
-- XP Data
iXPGraphPlots = {}
iXPTotalPlots = {}
iXPPerHour = 0
iXPTotalMinutePrevious = nil
iXPTotalMinuteCurrent = nil
iXPHighestPlot = 0
iXPPastHour = 0
iXPTotalRecordedIncoming = 0
iXPMinutesRecordedTotal = 0
-- Misc global variables
bLastRoomFailGMCP = true
bMapLocked = false
bTempUnlocked = false
sOldRoomID = ""
sThisRoomType = ""
bCreatingRooms = false
bIgnoreExits = true
sQuowLocationsByRoomID = {}
sQuowExitsByID = {}
sQuowExitsByExit = {}
sQuowShopItems = {}
sQuowUserBookmarks = {}
sSortedBookmarks = {}
iQuowCombatStats = {}
-- Default user options - default settings
sUSER_OPTIONS = {
-- Pick these colours
["col_special_prep"] = "#00FF7F",
["col_special_fail"] = "#FF6347",
["col_special_out_fail"] = "#FF6347",
["col_special_out_success"] = "#32CD32",
["col_melee_out_fail"] = "#F0E68C",
["col_melee_out_success"] = "yellowgreen",
["col_melee_out_kill"] = "#D6FFFF",
["col_special_inc_fail"] = "#DAA520",
["col_special_inc_success"] = "#FF4500",
["col_melee_inc_fail"] = "#7A7A57",
["col_melee_inc_success"] = "maroon",
["col_melee_inc_kill"] = "red",
["col_special_third_fail"] = "#3C4669",
["col_special_third_success"] = "#3C4420",
["col_melee_third_fail"] = "#3C4669",
["col_melee_third_success"] = "#3C4420",
["col_melee_third_kill"] = "#C7C9C9",
-- Omit these
["omit_special_prep"] = "n",
["omit_special_fail"] = "n",
["omit_special_out_fail"] = "n",
["omit_special_out_success"] = "n",
["omit_melee_out_fail"] = "n",
["omit_melee_out_success"] = "n",
["omit_melee_out_kill"] = "n",
["omit_special_inc_fail"] = "n",
["omit_special_inc_success"] = "n",
["omit_melee_inc_fail"] = "n",
["omit_melee_inc_success"] = "n",
["omit_melee_inc_kill"] = "n",
["omit_special_third_fail"] = "n",
["omit_special_third_success"] = "n",
["omit_melee_third_fail"] = "n",
["omit_melee_third_success"] = "n",
["omit_melee_third_kill"] = "n",
-- Don't colour there
["nocol_special_prep"] = 17,
["nocol_special_fail"] = 17,
["nocol_special_out_fail"] = 17,
["nocol_special_out_success"] = 17,
["nocol_melee_out_fail"] = 17,
["nocol_melee_out_success"] = 17,
["nocol_melee_out_kill"] = 17,
["nocol_special_inc_fail"] = 17,
["nocol_special_inc_success"] = 17,
["nocol_melee_inc_fail"] = 17,
["nocol_melee_inc_success"] = 17,
["nocol_melee_inc_kill"] = 17,
["nocol_special_third_fail"] = 17,
["nocol_special_third_success"] = 17,
["nocol_melee_third_fail"] = 17,
["nocol_melee_third_success"] = 17,
["nocol_melee_third_kill"] = 17,
-- Last version run by this user
["last_version_run"] = sPluginFullVersion,
-- For vitals bars
["vitals_hp_a"] = 36864,
["vitals_hp_b"] = 56797,
["vitals_hp_c"] = 255,
["vitals_gp_a"] = 15597568,
["vitals_gp_b"] = 10027076,
["vitals_gp_c"] = 6684774,
["vitals_b_a"] = 36864,
["vitals_b_b"] = 56797,
["vitals_b_c"] = 255,
}
iTotalUserOptions = 0
for sKey, sData in pairs(sUSER_OPTIONS) do
iTotalUserOptions = iTotalUserOptions + 1
end
iCurrentCombatStatSet = 0
-- Preserve old text rectangle data
iOldTextRectangleData = {0, 0, 0, 0}
-- Lock the screen margins
bLockMargins = true
if (GetVariable("bLockMargins") == "false") then
bLockMargins = false
end
if (GetVariable("MODULES") ~= nil) then
MODULES = json.decode(GetVariable("MODULES"))
else
MODULES = {
["minimap"] = true,
["mdt"] = true,
["vitals"] = true,
["xp"] = true,
["shields"] = true,
["stats"] = true,
["ascii"] = true,
["comms"] = true,
}
end
if (GetVariable("SCREENMARGINS") ~= nil) then
SCREENMARGINS = json.decode(GetVariable("SCREENMARGINS"))
else
SCREENMARGINS = {
["left"] = {true, 182},
["top"] = {false, 10},
["right"] = {false, 10},
["bottom"] = {false, 10},
}
end
if (GetVariable("CUSTOMCOWS") ~= nil) then
CUSTOMCOWS = json.decode(GetVariable("CUSTOMCOWS"))
if (CUSTOMCOWS["OPTIONS"] == nil) then
CUSTOMCOWS["OPTIONS"] = { ["STACK"] = true, }
end
else
CUSTOMCOWS = {
["MARGINS"] = {
["left"] = {true, 182},
["top"] = {false, 10},
["right"] = {false, 10},
["bottom"] = {false, 10},
},
[winMinimap] = { ["WIDTH"] = 250, ["HEIGHT"] = 250, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
[winMDT] = { ["WIDTH"] = 400, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
[winBars] = { ["WIDTH"] = 190, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
[winStats] = { ["WIDTH"] = 190, ["HEIGHT"] = 220, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
[winXP] = { ["WIDTH"] = 190, ["HEIGHT"] = 180, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
[winShields] = { ["WIDTH"] = 190, ["HEIGHT"] = 180, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
[winComms] = { ["WIDTH"] = 400, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
[winAscii] = { ["WIDTH"] = 80, ["HEIGHT"] = 80, ["SHOW"] = true, ["LOCKED"] = false, ["X"] = 0, ["Y"] = 0 },
["OPTIONS"] = { ["STACK"] = true, },
}
end
sSQL = ""
-- Escape a string safely for SQL queries
function EscapeSQL(s)
if s then
return string.gsub (s, "'", "''")
else
return ""
end
end
-- Check if a string starts with another string
function string.starts(sCheckThis, sFindThis)
return string.sub(sCheckThis, 1, string.len(sFindThis)) == sFindThis
end
-- Convert quantity of minutes to textual description with hours
function MinutesToTimeString(iMinutesIn)
if (iMinutesIn == 0) then
return "0 mins"
elseif (iMinutesIn == 1) then
return "1 min"
elseif (iMinutesIn < 61) then
return iMinutesIn .. " mins"
else
local iHours = math.floor(iMinutesIn / 60)
iMinutesIn = iMinutesIn - (iHours * 60)
return iHours .. "h " .. iMinutesIn .. "m"
end
end
function QuowBookmarkCompare(a, b)
return string.lower(a[2]) < string.lower(b[2])
end
-- Comma-separate long numbers
function NumberCommaString(iQuantity)
local sFormatted = iQuantity
while true do
sFormatted, iK = string.gsub(sFormatted, "^(-?%d+)(%d%d%d)", '%1,%2')
if (iK == 0) then
break
end
end
return sFormatted
end
-- Check folder location and database file
sDatabaseFile = sQuowMapPath .. "_quowmap_database.db"
iDBAttempts = 0
iDBStatus = DatabaseOpen("dbMap", sDatabaseFile, 1)
-- *************************************************
-- * Check on, load, import, create databases etc. *
-- *************************************************
while (iDBStatus ~= 0 and iDBAttempts < 2) do
DatabaseClose("dbMap")
iDBAttempts = iDBAttempts + 1
ColourNote("red", sGlobalColourBlack, "Quow's Cow Bar Fatal Error:")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Unable to find/load the room database file '_quowmap_database.db' in:")
ColourNote(sGlobalColourCyan, sGlobalColourBlack, sQuowMapPath)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Please navigate to and select the folder in the popup window!")
sNewMapPath = utils.directorypicker("Fatal Error!\nCannot find Quow's Cow Bar database!\nPlease locate your \\maps\\ folder:", "")
if (sNewMapPath ~= nil) then
sQuowMapPath = sNewMapPath .. "\\"
end
sDatabaseFile = sQuowMapPath .. "_quowmap_database.db"
iDBStatus = DatabaseOpen("dbMap", sDatabaseFile, 1)
end
if (iDBAttempts > 0) then
Note("")
ColourNote("red", sGlobalColourBlack, "Quow's Cow Bar Notice:")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your \\maps\\ folder has been successfully set to this location:")
ColourNote(sGlobalColourCyan, sGlobalColourBlack, sQuowMapPath)
end
DatabaseClose("dbMap")
if (iDBStatus ~= 0) then
Note("")
ColourNote("red", sGlobalColourBlack, "===== Quow's Cow Bar Fatal Error =====")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Unable to find/load the room database file '_quowmap_database.db' in your \\maps\\ folder!")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Please ensure you have downloaded the full Minimap.zip file, and extracted ALL the contents to a folder.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Ensure it contains a \\maps\\ folder containing 53 .png files, 4 .wav files, and IMPORTANTLY the _quowmap_database.db database file!")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "The plugin is now exiting and will not run.")
ColourNote("red", sGlobalColourBlack, "Reinstall the minimap plugin once you have corrected this.")
ColourNote("red", sGlobalColourBlack, "===== Quow's Cow Bar Fatal Error =====")
Note("")
-- Os.exit is not available in Mushclient, so this is a sneaky way to force-crash the plugin and exit it with errors.
os.exit()
else
dbMap = assert(sqlite3.open(sDatabaseFile))
for row in dbMap:nrows("SELECT room_id, map_id, xpos, ypos, room_short, room_type, shop_stocked FROM rooms") do
sQuowLocationsByRoomID[row.room_id] = {row.map_id, row.xpos, row.ypos, row.room_short, row.room_type, row.shop_stocked}
sQuowExitsByID[row.room_id] = {}
sQuowExitsByExit[row.room_id] = {}
if (row.shop_stocked == 1) then
sQuowShopItems[row.room_id] = {}
end
end
for row in dbMap:nrows("SELECT room_id, connect_id, exit FROM room_exits") do
if (sQuowExitsByID[row.room_id] ~= nil and sQuowExitsByID[row.connect_id] ~= nil) then
sQuowExitsByID[row.room_id][row.connect_id] = row.exit
sQuowExitsByExit[row.room_id][row.exit] = row.connect_id
end
end
for row in dbMap:nrows("SELECT room_id, stock_code, stock_name, stock_price FROM room_shop") do
if (sQuowShopItems[row.room_id] ~= nil) then
sQuowShopItems[row.room_id][row.stock_code] = {row.stock_name, row.stock_price}
end
end
dbUserData = assert(sqlite3.open(sQuowMapPath .. "_quowmap_userdata.db"))
sSQL = "CREATE TABLE IF NOT EXISTS user_options (option_id TEXT NOT NULL,option_value TEXT NOT NULL,PRIMARY KEY (option_id))"
assert(dbUserData:execute(sSQL))
local iTotalOptionsFound = 0
local bOptionsFound = {}
for row in dbUserData:nrows("SELECT option_id, option_value FROM user_options") do
sUSER_OPTIONS[row.option_id] = row.option_value
bOptionsFound[row.option_id] = true
iTotalOptionsFound = iTotalOptionsFound + 1
end
-- Insert any missing user options into the table
if (iTotalOptionsFound < iTotalUserOptions) then
sSQL = "INSERT INTO user_options (option_id, option_value) VALUES "
for sOptionKey, sOptionValue in pairs(sUSER_OPTIONS) do
if (bOptionsFound[sOptionKey] == nil) then
sSQL = sSQL .. "('" .. sOptionKey .. "', '" .. EscapeSQL(sOptionValue) .. "'),"
end
end
sSQL = string.sub(sSQL, 1, -2)
assert(dbUserData:execute(sSQL))
end
bAnyOptions = nil
sSQL = "CREATE TABLE IF NOT EXISTS bookmarks (room_id TEXT NOT NULL,note TEXT NOT NULL,PRIMARY KEY (room_id))"
assert(dbUserData:execute(sSQL))
for row in dbUserData:nrows("SELECT room_id, note FROM bookmarks") do
if (sQuowLocationsByRoomID[row.room_id] ~= nil) then
if (row.note == "") then
row.note = sQuowLocationsByRoomID[row.room_id][4]
end
sQuowUserBookmarks[row.room_id] = row.note
table.insert(sSortedBookmarks, {row.room_id, row.note})
end
end
table.sort(sSortedBookmarks, QuowBookmarkCompare)
-- Create the database table if this is a first run
sSQL = [[CREATE TABLE IF NOT EXISTS item_data (
item_name TEXT NOT NULL,
value_pence INTEGER NOT NULL DEFAULT '0',
PRIMARY KEY (set_id)
)]]
--assert(dbUserData:execute(sSQL))
-- Create the database table if this is a first run
sSQL = [[CREATE TABLE IF NOT EXISTS combat_stats (
set_id INTEGER NOT NULL,
set_name TEXT NOT NULL DEFAULT '',
gp_regen INTEGER NOT NULL DEFAULT '3',
rounds_total INTEGER NOT NULL DEFAULT '0',
kills_total INTEGER NOT NULL DEFAULT '0',
deaths_total INTEGER NOT NULL DEFAULT '0',
special_out_prepared INTEGER NOT NULL DEFAULT '0',
special_out_failprepared INTEGER NOT NULL DEFAULT '0',
hits_out_total INTEGER NOT NULL DEFAULT '0',
hits_out_landed INTEGER NOT NULL DEFAULT '0',
hits_out_zonefail INTEGER NOT NULL DEFAULT '0',
hits_out_defended INTEGER NOT NULL DEFAULT '0',
special_out_landed INTEGER NOT NULL DEFAULT '0',
special_out_defended INTEGER NOT NULL DEFAULT '0',
hits_out_defended_dodged INTEGER NOT NULL DEFAULT '0',
hits_out_defended_dodged_barely INTEGER NOT NULL DEFAULT '0',
hits_out_defended_dodged_normal INTEGER NOT NULL DEFAULT '0',
hits_out_defended_dodged_deftly INTEGER NOT NULL DEFAULT '0',
hits_out_defended_dodged_somehow INTEGER NOT NULL DEFAULT '0',
hits_out_defended_parried INTEGER NOT NULL DEFAULT '0',
hits_out_defended_parried_barely INTEGER NOT NULL DEFAULT '0',
hits_out_defended_parried_normal INTEGER NOT NULL DEFAULT '0',
hits_out_defended_parried_deftly INTEGER NOT NULL DEFAULT '0',
hits_out_defended_blocked INTEGER NOT NULL DEFAULT '0',
hits_out_defended_blocked_barely INTEGER NOT NULL DEFAULT '0',
hits_out_defended_blocked_normal INTEGER NOT NULL DEFAULT '0',
hits_out_defended_blocked_deftly INTEGER NOT NULL DEFAULT '0',
hits_out_armoured INTEGER NOT NULL DEFAULT '0',
hits_out_tpa INTEGER NOT NULL DEFAULT '0',
hits_out_bugs INTEGER NOT NULL DEFAULT '0',
hits_out_major INTEGER NOT NULL DEFAULT '0',
hits_out_ccc INTEGER NOT NULL DEFAULT '0',
hits_out_eff INTEGER NOT NULL DEFAULT '0',
hits_inc_total INTEGER NOT NULL DEFAULT '0',
hits_inc_landed INTEGER NOT NULL DEFAULT '0',
hits_inc_zonefail INTEGER NOT NULL DEFAULT '0',
special_inc_landed INTEGER NOT NULL DEFAULT '0',
special_inc_defended INTEGER NOT NULL DEFAULT '0',
hits_inc_defended INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_dodged INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_dodged_barely INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_dodged_normal INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_dodged_deftly INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_dodged_somehow INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_parried INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_parried_barely INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_parried_normal INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_parried_deftly INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_blocked INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_blocked_barely INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_blocked_normal INTEGER NOT NULL DEFAULT '0',
hits_inc_defended_blocked_deftly INTEGER NOT NULL DEFAULT '0',
hits_inc_armoured INTEGER NOT NULL DEFAULT '0',
hits_inc_tpa INTEGER NOT NULL DEFAULT '0',
hits_inc_bugs INTEGER NOT NULL DEFAULT '0',
hits_inc_major INTEGER NOT NULL DEFAULT '0',
hits_inc_ccc INTEGER NOT NULL DEFAULT '0',
hits_inc_eff INTEGER NOT NULL DEFAULT '0',
PRIMARY KEY (set_id)
)]]
assert(dbUserData:execute(sSQL))
-- Now load in all the sets and stats
for row in dbUserData:nrows("SELECT * FROM combat_stats") do
iQuowCombatStats[row.set_id] = {}
for sStatName, sStatValue in pairs(row) do
if (sStatName ~= "set_id") then
if (sStatName ~= "set_name") then
iQuowCombatStats[row.set_id][sStatName] = tonumber(sStatValue)
else
iQuowCombatStats[row.set_id][sStatName] = sStatValue
end
end
end
if (iCurrentCombatStatSet == 0) then
iCurrentCombatStatSet = row.set_id
end
end
-- Create default blank stat sets
if (iCurrentCombatStatSet == 0) then
iCurrentCombatStatSet = 1
assert(dbUserData:execute("INSERT INTO combat_stats (set_id, set_name) VALUES (1, 'Set One'),(2, 'Set Two'),(3, 'Set Three'),(4, 'Set Four'),(5, 'Set Five')"))
for row in dbUserData:nrows("SELECT * FROM combat_stats") do
iQuowCombatStats[row.set_id] = {}
for sStatName, sStatValue in pairs(row) do
if (sStatName ~= "set_id") then
if (sStatName ~= "set_name") then
iQuowCombatStats[row.set_id][sStatName] = tonumber(sStatValue)
else
iQuowCombatStats[row.set_id][sStatName] = sStatValue
end
end
end
end
end
-- Do necessary database updates when detecting a version upgrade
if (sUSER_OPTIONS["last_version_run"] ~= sPluginFullVersion) then
-- Missing zonefail column, add it in
if (iQuowCombatStats[1]["hits_inc_zonefail"] == nil) then
Tell("[updating database columns] ")
-- Do stuff based on their previous version number
assert(dbUserData:execute("ALTER TABLE combat_stats ADD COLUMN hits_inc_zonefail INTEGER NOT NULL DEFAULT '0'"))
assert(dbUserData:execute("ALTER TABLE combat_stats ADD COLUMN hits_out_zonefail INTEGER NOT NULL DEFAULT '0'"))
for iN = 1, 5 do
iQuowCombatStats[iN]["hits_inc_zonefail"] = 0
iQuowCombatStats[iN]["hits_out_zonefail"] = 0
end
end
-- Update their stored Cow Var version
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. sPluginFullVersion .. "' where option_id='last_version_run'"))
ColourNote(sGlobalColourCyan, sGlobalColourBlack, "Quow's Cow Bar plugin has been updated from an old version (" .. sUSER_OPTIONS["last_version_run"] .. " to " .. sPluginFullVersion .. "). Thank you for updating!")
sUSER_OPTIONS["last_version_run"] = sPluginFullVersion
end
end
-- **********************************************************************
-- * Help File Text *
-- **********************************************************************
function DisplayHelpFile (sName, sLine, wildcards)
Note("")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar & Minimap Plugin Helpfile:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "help minimap")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : This help information")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap hide")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Hide the minimap window (still runs in the background)")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap show")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Show the minimap window")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Display your selected map co-ordinates in command form, for other users to paste & see")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap {map, x, y}")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Jump to exact co-ordinates, eg 'minimap {1, 719, 803}' will jump to the Drum")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap <dir>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Snap the map in the specified direction without sending that command to the mud")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap setdir <dir>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Snap the map in the specified direction without sending that command to the mud")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap discworldconfig")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "': Set/Change your Discworld-side options that may fix some problems")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap mushconfig")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "': Set/Change your MUSHclient-side options that may fix some problems")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap reset")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Fix problems by resetting the minimap and all other windows back to default settings, sizes and locations")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap <corner>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Snap the minimap into a corner, eg 'minimap topleft', 'minimap bottomright'")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap brightness <x>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Set the minimap window brightness from 50-100%, eg 'minimap brightness 90'")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap resize X,Y")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Resize the minimap window, eg 'minimap resize 300,300'")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap route <number>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Try to speedwalk to a place or item search result number")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap route <bookmark>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Try to find a matching bookmark and immediately speedwalk to it")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap bookmarks")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Display your bookmarked rooms; Bookmark a selected room in the right-click map menu")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " Or use 'minimap bookmark' to bookmark the room you are currently stood in")
--Note("")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap item <item>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Search item database for standard shop-stock items and provides shortcut links")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " eg 'minimap item beeswax', 'minimap item pink doughnut'")
--Note("")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "minimap <placename>")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "' : Search location database matching [short room names] and provides shortcut links")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " eg 'minimap attic bee', 'minimap drum'")
Note("")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "* Click-drag the minimap titlebar to move the window around.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "* Left-Clicking on the map will centre the map on that location (and snap to nearby rooms).")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "* Shift-Left-Clicking will take you to any connected/adjacent/zoomed-in maps (eg shift-click the thieves guild, or from within the thieves guild shift-click the street exit).")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "* Right-clicking on the map will bring up a context menu with options and extra commands: Change maps, Speedwalk to location, display shop listings or room info, reset map position etc.")
Note("")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "--- End of help file ---")
end
-- **********************************************************************
-- * Global Table Setups *
-- **********************************************************************
-- Special Long Descriptions for places without a Room ID
sQuowLocationsByLong = {
[1] = {"UULibraryExit", "^This is the south end of the Library of Unseen University\. The rows and rows of bookshelves start just to the north and the door out is to the south\."},
[2] = {"UULibraryGap", "^This is somewhere in the Library of Unseen University\. There is a strange gap in the shelves here\."},
[3] = {"ShadesEntrance", "^This is deep in the Shades\. What passes for civilization in these parts is to the west, but otherwise there are three alleyways in weaving twisting directions which don't appear on any compass\. Further in is a deadly maze of dangerous alleyways\."},
[4] = {"Shades2", "^Deep, deep into the Shades\. This alley is like every other alley in this rabbit warren of death\. It is dank, dark and foggy, everything looks the same\.\.\."},
[5] = {"Shades5", "^This rabbit warren of smoky, hazy alleys is never ending\. The gloom and fog mask the direction of the screams that echo in the distance\.\.\."},
[6] = {"Shades8", "^Deep, deep into the Shades\. This alleyway is like every other alleyway in this rabbit warren of death\. It is dank, dark and foggy, everything looks the same\.\.\."},
[7] = {"Shades9", "^This dark, dank, foggy alleyway leads to other dark dank foggy alleyways\. The gloom hides the worst of the horrors that these alleys contain\."},
[8] = {"Shades12", "^This room is like any of the other alleyways, dank, dark and foggy\. It has lots of exits that lead to other dank, dark and foggy alleyways\. Howls of fear and pain echo around from the walls\."},
[9] = {"Shades16", "^The Lady is evidently not on your side; at every turn lies another twisting alleyway\. Dim torches flicker red through the fog, providing more a sinister red glow than any real light\."},
[10] = {"SweetheartMazeBegin", "^Deep in the Shades, it becomes obvious that Sweetheart Lane is perhaps slightly misnamed\. A dim red light glows to the south in Romeo Street, signifying some kind of life, whilst only the fog is visible to the east and west\."},
--[[
Slippery Hollow forest rooms, no use
[11] = {"Forest1", "^Tree branches twist like the tentacles of a deranged sea monster through the rank gloom all around\. Even in this darkness undergrowth abounds, although it drips with strange, sticky fluids\. A large stone, carved with mysterious symbols sits on a bare patch of ground among the undergrowth\."},
[12] = {"Forest2", "^Trees crowd darkly on all sides, struggling against each other for space and the light that never comes\. Among the trees you frequently sense movement in the darkness, as if creatures were massing to attack\. A large swathe of undergrowth has been uprooted, as if something has been digging here\."},
[13] = {"Forest3", "^Trees crowd darkly on all sides, struggling against each other for space and the light that never comes\. Some of the trees have been used as scratching posts as they bear some very large claw marks\. A large swathe of undergrowth has been uprooted, as if something has been digging here\."},
[14] = {"Forest4", "^Trees everywhere! It's to be expected in a forest, but at least most forests manage nicer trees\. Moss, mould, lichen and other less recognisable substances coat the surfaces of the trees\. Large stone blocks are scattered among the undergrowth as if a building once stood nearby\."},
[15] = {"Forest5", "^Tree branches twist like the tentacles of a deranged sea monster through the rank gloom all around\. The smell of decay and mould drifts from the dying vegetation\.\.\. and perhaps from less obvious sources. Strange, pale tendrils dangle from above like slender tentacles; hopefully just foliage\."},
[16] = {"Forest6", "^Tree branches twist like the tentacles of a deranged sea monster through the rank gloom all around\. The strange undergrowth makes walking here tricky as it tends to snag the feet of the unwary\. A large stone, carved with mysterious symbols sits on a bare patch of ground among the undergrowth\."},
[17] = {"Forest7", "^Trees crowd darkly on all sides, struggling against each other for space and the light that never comes\. Several of the tree branches are broken as if something very large came through here at speed\. Large stone blocks are scattered among the undergrowth as if a building once stood nearby\."},
[18] = {"Forest8", "^Pallid tree trunks surround you, their branches strangely twisted as if the very trees were mad\. Glowing eyes peek between the trees on every side, although they seem to belong to varied species\. A large stone, carved with mysterious symbols sits on a bare patch of ground among the undergrowth\."},
[19] = {"Forest9", "^The trees stand as impassive witnesses to the many horrors of this dark and sickly forest\. Moss, mould, lichen and other less recognisable substances coat the surfaces of the trees\. A large stone, carved with mysterious symbols sits on a bare patch of ground among the undergrowth\."},
[20] = {"Forest0", "^It is hard to tell the species of the trees in this forest, so deformed have the trees become\. Even in this darkness undergrowth abounds, although it drips with strange, sticky fluids\. A skeleton lies amid the strange undergrowth, clearly not human but not easy to identify either\."},
[21] = {"ForestA", "^Trees crowd darkly on all sides, struggling against each other for space and the light that never comes\. Moss, mould, lichen and other less recognisable substances coat the surfaces of the trees\. Large stone blocks are scattered among the undergrowth as if a building once stood nearby\."},
[22] = {"ForestB", "^Pallid tree trunks surround you, their branches strangely twisted as if the very trees were mad\. Glowing eyes peek between the trees on every side, although they seem to belong to varied species\. A large swathe of undergrowth has been uprooted, as if something has been digging here\."},
[23] = {"ForestC", "^The trees here almost seem to be weaving their branches into barriers to halt the progress of travellers\. The smell of decay and mould drifts from the dying vegetation\.\.\. and perhaps from less obvious sources\. Flies buzz urgently around the area, perhaps indicating a decaying body nearby\."},
[24] = {"ForestD", "^Trees everywhere! It's to be expected in a forest, but at least most forests manage nicer trees\. Some of the trees have been used as scratching posts as they bear some very large claw marks\. Flies buzz urgently around the area, perhaps indicating a decaying body nearby\."},
[25] = {"ForestE", "^Damp bark peels from the sickly trees all around as if they are diseased in some way\. Even in this darkness undergrowth abounds, although it drips with strange, sticky fluids\. A large swathe of undergrowth has been uprooted, as if something has been digging here\."},
[26] = {"ForestF", "^Gnarled, pale branches, like the hands of deformed corpses, reach out blindly from twisted tree trunks\. Glowing eyes peek between the trees on every side, although they seem to belong to varied species\. A large swathe of undergrowth has been uprooted, as if something has been digging here\."},
[27] = {"ForestG", "^Tree branches twist like the tentacles of a deranged sea monster through the rank gloom all around\. Moss, mould, lichen and other less recognisable substances coat the surfaces of the trees\. A vast mound of black-capped fungi rears through the undergrowth here like a small hill\."},
--]]
}
-- Special [short room names] for places without a Room ID
sQuowLocationsByShort = {
-- AM Shades Maze [8]
["ShadesEntrance"] = {8, 48, 174},
["Shades2"] = {8, 206, 16},
["Shades5"] = {8, 364, 174},
["Shades8"] = {8, 206, 332},
["Shades9"] = {8, 127, 253},
["Shades12"] = {8, 285, 95},
["Shades16"] = {8, 206, 174},
-- UU Library [47]
["UULibraryExit"] = {47, 166, 4810},
["UULibraryGap"] = {47, 196, 4480},
}
-- Terrain room detects
sQuowTerrainRooms = {
["mountain"] = {0}, -- Ramtops
["edge of a desert near a swamp"] = {0}, -- Far west of DJB
["swamp edge near a desert"] = {0}, -- Far west of DJB
["swamp"] = {0}, -- Far west of DJB
["desert"] = {0}, -- Far west of DJB
["melon farm"] = {0}, -- Outside of DJB
["water pasture"] = {0},
["cliff"] = {0},
["edge of plains near some cliffs and a rocky shore"] = {0},
["edge of plains near some cliffs and cabbage fields"] = {0},
["edge of plains near a beach"] = {0},
["moorland close to a mixed forest and a mountain range"] = {0},
["edge of cabbage fields near some plains and a forest"] = {0},
["garlic farm"] = {0}, -- Outside of DJB
["deciduous forest close to a mountain range and an evergreen forest"] = {0},
["deciduous forest close to some plains"] = {0},
["plains close to a deciduous forest"] = {0},
["evergreen forest close to a mountain range and a deciduous forest"] = {0},
["deciduous forest close to a mountain range"] = {0},
["deciduous forest close to a lake"] = {0},
["deciduous forest close to a mountain range and a lake"] = {0},
["deciduous forest close to a gorge and a lake"] = {0},
["tomato farm"] = {0}, -- Outside of EPhebe
["grass savanna"] = {0}, -- Outside of DJB, Ephebe, etc.
["shrub savanna"] = {0}, -- Outside of DJB, Ephebe, etc.
["savanna near the edge of a plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["edge of plains near a savanna"] = {0}, -- Outside of DJB, Ephebe, etc.
["dry plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["parched plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["dry grassland"] = {0}, -- Outside of DJB, Ephebe, etc.
["beach"] = {0}, -- Near any coast
["rocky shore"] = {0}, -- Rocky shores outside of Ephebe/AM
["edge of plains near a beach and a rocky shore"] = {0},
["plains with sandy soil"] = {0}, -- Near coastal plains
["deciduous forest close to an evergreen forest and a marsh"] = {0},
["Uberwald forest"] = {0},
["melon farm under a fig tree"] = {0},
["dark woods close to a mountain range"] = {0},
["deep, dark forest"] = {0},
["Uberwald forest close to a mountain range"] = {0},
["deep, dark forest close to a mountain range"] = {0},
["deep expanses of a forest"] = {0},
["forest trail"] = {0},
["Uberwald forest close to a marsh"] = {0},
["deep, dark forest close to a marsh"] = {0},
["deep, dark forest close to an evergreen forest"] = {0},
["dark woods close to an evergreen forest"] = {0},
["Uberwald forest close to an evergreen forest"] = {0},
["evergreen forest close to a mixed forest"] = {0},
["deep expanses of a forest close to a mountain range"] = {0},
["deep expanses of a forest close to a mountain range and a lake"] = {0},
["deep, dark forest close to a mountain range and a lake"] = {0},
["Uberwald forest close to a lake"] = {0},
["dark woods"] = {0},
["deep, dark forest close to a mountain range and some tundra"] = {0},
["Uberwald forest close to a mountain range and some tundra"] = {0},
["moorland close to a mountain range and a mixed forest"] = {0},
["dark woods close to a mountain range and some tundra"] = {0},
["edge of a forest near some mountains"] = {0},
["edge of a forest near some plains"] = {0}, -- Outside of sto lat
["edge of plains near some cliffs"] = {0}, --Outside of DJB
["edge of plains near a stand of trees"] = {0}, -- Outside of DJB, Ephebe, etc.
["edge of a jungle near some plains"] = {0}, -- Outside of DJB, Ephebe, etc.
["arid plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["jungle"] = {0}, -- Outside of DJB, Ephebe, etc.
["Ephebian desert"] = {0}, -- Outside of DJB, Ephebe, etc.
["Ephebian desert near a plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["flourishing plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["savanna near the edge of a desert"] = {0},
["edge of Tsortean desert near a savanna"] = {0},
["verdant plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["lush plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["some plains"] = {0}, -- Outside of DJB, Ephebe, etc.
["grassy plain"] = {0}, -- Outside of DJB, Ephebe, etc.
["edge of plains near a lake"] = {0},
["tree savanna"] = {0},
["lightly wooded area with a grassy floor"] = {0},
["edge of a jungle near a savanna"] = {0},
["savanna near some mountains"] = {0},
["edge of plains near some cabbage fields"] = {0},
["cabbage fields"] = {0},
["edge of a forest near some plains and a lake"] = {0},
["edge of a rainforest near some plains"] = {0},
["rainforest"] = {0},
["edge of a rainforest near some swamp"] = {0},
["swamp edge near some rainforest"] = {0},
["edge of some plains near some cabbage fields"] = {0}, -- Around Am and Sto-Lat
["some cabbage fields"] = {0}, -- Around Am and Sto-Lat
["in some cabbage fields"] = {0},
["edge of plains near some cabbage fields and a forest"] = {0},
["cabbage fields near a stand of trees"] = {0},
["in a forest, near some cabbage fields"] = {0},
["forest"] = {0},
["dense marshland close to a deciduous forest"] = {0},
["deciduous forest close to a marsh"] = {0},
["dense marshland"] = {0},
["dark forest"] = {0},
["edge of a forest near a lake"] = {0},
["edge of plains near a stand of trees and a rocky shore"] = {0},
["plains near some mountains"] = {0}, -- South of AM
["hilly mountain range"] = {0}, -- South of AM
["deciduous forest close to a gorge"] = {0}, -- Outside of Lancre north
["evergreen forest"] = {0}, -- outside of Gloomy
["evergreen forest close to some tundra"] = {0}, -- Outside of Creel
["deciduous forest"] = {0}, -- outside of Gloomy
["evergreen forest close to a deciduous forest"] = {0}, -- outside of Gloomy
["moorland"] = {0},
["deciduous forest close to an evergreen forest"] = {0}, -- outside of Gloom
["moorland close to a mountain range, an evergreen forest and a deciduous forest"] = {0}, -- Outside of Creel
["moorland close to a mountain range and an evergreen forest"] = {0}, -- Outside of Creel
["moorland close to a mountain range"] = {0}, -- Outside of Creel
["moorland close to a mountain range and a deciduous forest"] = {0}, -- Outside of Creel
["rocky ground in the middle of the moorland"] = {0}, -- Outside of Creel
["moorland close to a mountain range, an evergreen forest and a deciduous forest"] = {0}, -- Outside of Creel
["moorland close to an evergreen forest and a deciduous forest"] = {0}, -- Outside of Creel
["moorland close to a deciduous forest"] = {0}, -- Outside of Creel
["deciduous forest close to some tundra"] = {0}, -- Outside of Creel
["evergreen forest close to a mountain range"] = {0}, -- Outside of Creel
}
-- **********************************************************************
-- * Map Find Strings - For Quick Map Changes! *
-- **********************************************************************
-- These are "quick/short names" to zip to maps from typing "minimap <place>".
-- You can provide 3 arguments instead of 1, to specify the pixel location on the given map ID to zip to
-- eg ["drum"] = {1, 719, 803}
-- Otherwise default positions for that map will be used
sQuowPlaceLookups = {
["am"] = {1, "Ankh-Morpork"},
["ankh-morpork"] = {1, "Ankh-Morpork"},
["ankh"] = {1, "Ankh-Morpork"},
["morpork"] = {1, "Ankh-Morpork"},
["drum"] = {1, "The Drum"},
["assassins"] = {2, "Assassins Guild, Ankh-Morpork"},
["am assassins"] = {2, "Assassins Guild, Ankh-Morpork"},
["am buildings"] = {3, "Building Interiors, Ankh-Morpork"},
["shaker"] = {4, "Salt Shaker"},
["cruet"] = {4, "Cruet, Ankh-Morpork"},
["am docks"] = {5, "Docks, Ankh-Morpork"},
["docks"] = {5, "Docks, Ankh-Morpork"},
["am guilds"] = {6, "Non-Player Guilds, Ankh-Morpork"},
["guilds"] = {6, "Non-Player Guilds, Ankh-Morpork"},
["isle of gods"] = {7, "Isle of Gods Interiors, Ankh-Morpork"},
["shades"] = {8, "Shades Maze, Ankh-Morpork"},
["smallgods"] = {9, "TOSG, Ankh-Morpork"},
["small gods"] = {9, "TOSG, Ankh-Morpork"},
["tosg"] = {9, "TOSG, Ankh-Morpork"},
["temples"] = {10, "Temples, Ankh-Morpork"},
["thieves"] = {11, "Thieves Guild, Ankh-Morpork"},
["am thieves"] = {11, "Thieves Guild, Ankh-Morpork"},
["university"] = {12, "Unseen University, Ankh-Morpork"},
["unseen university"] = {12, "Unseen University, Ankh-Morpork"},
["uu"] = {12, "Unseen University, Ankh-Morpork"},
["warriors"] = {13, "Warrior Guilds, Ankh-Morpork"},
["watch"] = {14, "Pseudopolis Watch House, Ankh-Morpork"},
["watch house"] = {14, "Pseudopolis Watch House, Ankh-Morpork"},
["magpyr"] = {15, "Count Magpyr's Castle"},
["magpyrs"] = {15, "Count Magpyr's Castle"},
["count magpyr"] = {15, "Count Magpyr's Castle"},
["castle"] = {15, "Count Magpyr's Castle"},
["magpyr castle"] = {15, "Count Magpyr's Castle"},
["bois"] = {16, "Bois"},
["bp"] = {17, "Bes Pelargic"},
["bes pelargic"] = {17, "Bes Pelargic"},
["bp buildings"] = {18, "Bes Pelargic building interiors"},
["bp estates"] = {19, "Bes Pelargic family estates"},
["estates"] = {19, "Bes Pelargic family estates"},
["family estates"] = {19, "Bes Pelargic family estates"},
["tang estate"] = {19, "Tang Estate, Bes Pelargic", 77, 171},
["hong estate"] = {19, "Hong Estate, Bes Pelargic", 443, 155},
["sung estate"] = {19, "Sung Estate, Bes Pelargic", 897, 158},
["fang estate"] = {19, "Fang Estate, Bes Pelargic", 526, 506},
["mcsweeney estate"] = {19, "McSweeney Estate, Bes Pelargic", 899, 647},
["tangs"] = {19, "Tang Estate, Bes Pelargic", 77, 171},
["hongs"] = {19, "Hong Estate, Bes Pelargic", 443, 155},
["sungs"] = {19, "Sung Estate, Bes Pelargic", 897, 158},
["fangs"] = {19, "Fang Estate, Bes Pelargic", 526, 506},
["mcsweeneys"] = {19, "McSweeney Estate, Bes Pelargic", 899, 647},
["bp wizards"] = {20, "Wizard Guild, Bes Pelargic"},
["brown islands"] = {21, "Brown Islands"},
["death"] = {22, "Death's Domain"},
["deaths domain"] = {22, "Death's Domain"},
["death's domain"] = {22, "Death's Domain"},
["djb"] = {23, "Djelibeybi"},
["djelibeybi"] = {23, "Djelibeybi"},
["djb walls"] = {23, "Djelibeybi Walls", 498, 215},
["walls"] = {23, "Djelibeybi Walls", 498, 215},
["djb wall"] = {23, "Djelibeybi Walls", 498, 215},
["wall"] = {23, "Djelibeybi Walls", 498, 215},
["djb wizards"] = {24, "IIL - Djelibeybi Wizard Guild"},
["iil"] = {24, "IIL - Djelibeybi Wizard Guild"},
["ephebe"] = {25, "Ephebe"},
["ephebe docks"] = {26, "Ephebe Docks"},
["smugglers"] = {26, "Smuggler Caves, Ephebe Docks"},
["smuggler caves"] = {26, "Smuggler Caves, Ephebe Docks"},
["genua"] = {27, "Genua"},
["genua sewers"] = {28, "Genua Sewers"},
["sewers"] = {28, "Genua Sewers"},
["grflx"] = {29, "GRFLX Caves"},
["grflx caves"] = {29, "GRFLX Caves"},
["hashishim"] = {30, "Hashishim Caves"},
["hashishim caves"] = {30, "Hashishim Caves"},
["klatch"] = {31, "Klatch Region"},
["kfl"] = {31, "Klatchian Foreign Legion"},
["lancre kingdom"] = {32, "Lancre Kingdom"},
["lancre castle"] = {32, "Lancre Castle"},
["mano"] = {33, "Mano Rossa Assassin Guild"},
["mano rossa"] = {33, "Mano Rossa Assassin Guild"},
["monks of cool"] = {34, "Monks of Cool temple"},
["monks"] = {34, "Monks of Cool temple"},
["cool monks"] = {34, "Monks of Cool temple"},
["netherworld"] = {35, "Netherworld"},
["oasis"] = {36, "Oasis"},
["pumpkin town"] = {37, "Pumpkin Town"},
["newbie town"] = {37, "Pumpkin Town"},
["pumpkintown"] = {37, "Pumpkin Town"},
["ramtops"] = {38, "Ramtops Region"},
["gloomy"] = {38, "Gloomy Forest", 660, 269},
["gloomy forest"] = {38, "Gloomy Forest", 660, 269},
["bandits"] = {38, "Bandit Camp", 548, 199},
["bandit camp"] = {38, "Bandit Camp", 548, 199},
["oc"] = {38, "Ohulan-Cutash"},
["ohulan-cutash"] = {38, "Ohulan-Cutash"},
["ohulan cutash"] = {38, "Ohulan-Cutash"},
["hunters"] = {38, "Hunters Guild", 1284, 49},
["madstoat"] = {38, "Mad Stoat", 1443, 357},
["mad-stoat"] = {38, "Mad Stoat", 1443, 357},
["mad stoat"] = {38, "Mad Stoat", 1443, 357},
["brass neck"] = {38, "Brass Neck", 1486, 129},
["brassneck"] = {38, "Brass Neck", 1486, 129},
["brass-neck"] = {38, "Brass Neck", 1486, 129},
["badass"] = {38, "Bad Ass", 1666, 210},
["bad-ass"] = {38, "Bad Ass", 1666, 210},
["bad ass"] = {38, "Bad Ass", 1666, 210},
["lancre"] = {38, "Lancre", 1580, 589},
["lancre town"] = {38, "Lancre", 1580, 589},
["creel"] = {38, "Creel Springs", 1832, 632},
["creel springs"] = {38, "Creel Springs", 1832, 632},
["creel-springs"] = {38, "Creel Springs", 1832, 632},
["madwolf"] = {38, "Mad Wolf", 2058, 670},
["mad-wolf"] = {38, "Mad Wolf", 2058, 670},
["mad wolf"] = {38, "Mad Wolf", 2058, 670},
["razorback"] = {38, "Razorback", 1998, 393},
["slice"] = {38, "Slice", 2208, 280},
["giants"] = {38, "Ramtops Giants", 1893, 149},
["brigands"] = {38, "Ramtops Brigands", 1893, 149},
["soyin"] = {38, "Temple of Soyin", 1959, 252},
["listeners"] = {38, "Listening Monk Temple", 2171, 136},
["listener monks"] = {38, "Listening Monk Temple", 2171, 136},
["listening monks"] = {38, "Listening Monk Temple", 2171, 136},
["temple of listening monks"] = {38, "Listening Monk Temple", 2171, 136},
["summer camp"] = {46, "Barbarian Summer Camp", 2354, 103},
["sto-lat"] = {39, "Sto-Lat"},
["sto lat"] = {39, "Sto-Lat"},
["stolat"] = {39, "Sto-Lat"},
["sl"] = {39, "Sto-Lat"},
["sto"] = {39, "Sto-Lat"},
["aoa"] = {40, "Academy of Artificers, Sto-Lat Wizard Guild"},
["sto lat wizards"] = {40, "Academy of Artificers, Sto-Lat Wizard Guild"},
["cabbages"] = {41, "Cabbage Warehouse, Sto-Lat"},
["cabbage warehouse"] = {41, "Cabbage Warehouse, Sto-Lat"},
["aoa library"] = {42, "Academy of Artificers Library"},
["stolat sewers"] = {43, "Sto-Lat Sewers"},
["sl sewers"] = {43, "Sto-Lat Sewers"},
["sto-lat sewers"] = {43, "Sto-Lat Sewers"},
["sprites"] = {44, "Sprite Caves"},
["sprite caves"] = {44, "Sprite Caves"},
["sprite caverns"] = {44, "Sprite Caves"},
["sto plains"] = {45, "Sto Plains Region", 752, 390},
["stoplains"] = {45, "Sto Plains Region", 752, 390},
["holy wood"] = {45, "Holywood", 98, 139},
["holywood"] = {45, "Holywood", 98, 139},
["nowhere"] = {45, "Nowhere", 265, 760},
["sheepridge"] = {45, "Sheepridge", 618, 574},
["sheep ridge"] = {45, "Sheepridge", 618, 574},
["dinky"] = {45, "Dinky", 752, 390},
["scrodgen"] = {45, "Scrodgen", 1025, 263},
["bleak prospect"] = {45, "Bleak Prospect", 1213, 249},
["bleak"] = {45, "Bleak Prospect", 1213, 249},
["bleakprospect"] = {45, "Bleak Prospect", 1213, 249},
["hillshire"] = {45, "Hillshire", 1372, 467},
["pekan ford"] = {45, "Pekan Ford", 1393, 617},
["pf"] = {45, "Pekan Ford", 1393, 617},
["hedge"] = {45, "Hedge Wizard Guild", 1440, 546},
["hedges"] = {45, "Hedge Wizard Guild", 1440, 546},
["uberwald"] = {46, "Uberwald Region"},
["blackglass"] = {46, "Black Glass", 444, 187},
["black glass"] = {46, "Black Glass", 444, 187},
["escrow"] = {46, "Escrow", 673, 643},
["unnamed"] = {46, "Unnamed Town, Escrow", 977, 627},
["unnamed town"] = {46, "Unnamed Town, Escrow", 977, 627},
["winter camp"] = {46, "Barbarian Winter Camp", 1737, 1076},
["library"] = {47, "Unseen University Library"},
["uu library"] = {47, "Unseen University Library"},
["farms"] = {48, "Klatchian Farmsteads"},
["farmsteads"] = {48, "Klatchian Farmsteads"},
["chronides farmstead"] = {48, "Chronides Farmstead, Ephebe"},
["ctf arena"] = {49, "CTF Arena, Sto-Plains"},
["pk arena"] = {50, "PK Arena, Klatch"},
["post office"] = {51, "Post Office, Ankh-Morpork"},
["po"] = {51, "Post Office, Ankh-Morpork"},
["am po"] = {51, "Post Office, Ankh-Morpork"},
}
-- **********************************************************************
-- * Hot Zones - For Shift-Clickthrough Maps! *
-- **********************************************************************
local bRecordingHotzones = false
sQuowHotZones = {
{1, 825, 853, 836, 860, 'bd0e4420d659d994ea286a1e3f12097dd4f5c370'}, -- Ankh-Morpork to AM Post Office(northeast corner of the grand hall)
{51, 163, 0, 251, 59, '7495829293caa3876b2b13378d4c76bb75ca28cf'}, -- AM Post Office to Ankh-Morpork(junction of Widdershins Broadway and God Street)
{51, -1, 49, 58, 111, '16f977ddd1ad080a00ddd0253f3660fc14629554'}, -- AM Post Office to Ankh-Morpork(God Street south of the Fools' Guild)
{1, 826, 743, 837, 748, 'fca4d62329576c1387d4c7e0299abd6adc3b10f6'}, -- Ankh-Morpork to entrance hall of the Thieves' Guild
{11, 452, 292, 531, 310, 'f54759e82fd29dadcba06c2d6a1e41906e87c2e3'}, -- AM Thieves to Ankh-Morpork(Near the southern end of the Street of Alchemists)
{1, 845, 659, 851, 665, 'dec775b5d640412091a37ec2ca08c3877e1957c8'}, -- Ankh-Morpork to AM Guilds(courtyard in front of the Guild of Alchemists)
{6, 516, 301, 571, 318, 'ff1bfa1cc5cb3e4fca0fbd0e716a2d670d81464c'}, -- AM Guilds to Ankh-Morpork(Street of Alchemists outside its namesake guild)
{1, 952, 640, 1003, 655, '895dcc5d6f68d74435e139d9f71c1676283a9ecf'}, -- Ankh-Morpork to Unseen University(southeast corner of the Courtyard)
{12, 361, 412, 407, 429, 'c2e093b06399946c7b08edb9b5ce4617390cdedf'}, -- Unseen University to Ankh-Morpork(western edge of Sator Square)
{12, 463, 546, 517, 565, '61dfac4bf925ec6158e167375d3c274942ec3307'}, -- Unseen University to Ankh-Morpork(Peach Pie Street)
{1, 1078, 642, 1127, 655, '03d78b3b0885c5e931b7bf92b7c935c85796a0e3'}, -- Ankh-Morpork to AM Buildings(entrance hall of the Magical Supplies Emporium)
{3, 330, 408, 371, 427, '8426baac873bf2cce1a78d50e1c15b9def0ba829'}, -- AM Buildings to Ankh-Morpork(eastern edge of Sator Square)
{1, 1076, 310, 1089, 345, '0e593a9bd77a2fcf8ba4b802216b2a5084cdeb2e'}, -- Ankh-Morpork to AM Buildings(garden outside Milords and Miladies Pavilion)
{3, 466, 36, 512, 66, 'f653670a6ee9e7868919a5b6b15ce7148acb16d0'}, -- AM Buildings to Ankh-Morpork(bend in Spa Lane)
{1, 799, 798, 808, 816, '45c52ccb69e606bf7a125680c3de4952fc8e558b'}, -- Ankh-Morpork to AM Assassins(courtyard of the Assassins' Guild)
{2, 433, 3, 484, 35, '1864e5e81160a3d2db87a28d020fd003addb0cde'}, -- AM Assassins to Ankh-Morpork(east end of Filigree Street)
{1, 852, 742, 858, 749, '22ff3625b21dcb14ad35a521d4dfa9dc645f8d71'}, -- Ankh-Morpork to AM Guilds(main entrance of the Butchers' Guild)
{6, 710, 84, 768, 103, 'f54759e82fd29dadcba06c2d6a1e41906e87c2e3'}, -- AM Guilds to Ankh-Morpork(Near the southern end of the Street of Alchemists)
{1, 837, 715, 844, 722, '80e55d7eb45d374a851e517007926a388fb0314d'}, -- Ankh-Morpork to AM Guilds(large courtyard)
{6, 36, 81, 75, 106, 'da0311f4bdcba1f5f7c4b98cb00d9e81c395e8a1'}, -- AM Guilds to Ankh-Morpork(Pleaders Row outside the Plumbers' Guild)
{1, 785, 893, 809, 906, '13d50edc24a1918ff4109cad399d1b5566fb2b74'}, -- Ankh-Morpork to AM Guilds(waiting room of the Musicians' Guild)
{6, 114, 308, 151, 337, 'f1cf803e6332816be0dad0ef569fd3dfc03813cf'}, -- AM Guilds to Ankh-Morpork(Baker Street)
{1, 727, 996, 749, 1014, '454f863eb451dcbbf77ef3ae9e514a63595ffab9'}, -- Ankh-Morpork to AM Guilds(Bankers' Guild entrance)
{6, 325, 442, 387, 465, '4dd1faccaf3764ff27cdd4751f48792a6d60ce6a'}, -- AM Guilds to Ankh-Morpork(Street of Bookkeepers)
{1, 798, 926, 811, 934, '5f681501331ad44f421ce50f519a648f59a8b7f0'}, -- Ankh-Morpork to AM Temples(entrance hall)
{10, 690, 160, 743, 191, 'a0ee7454545f31ed763a0ce39ae866c89d2ed5d0'}, -- AM Temples to Ankh-Morpork(Street of Small Gods)
{1, 846, 922, 859, 933, 'c98c61ffc03009b8e428f7c3dd745a586f445478'}, -- Ankh-Morpork to AM Temples(entranceway of the cathedral of Gufnork)
{10, 194, 389, 242, 416, '5aa065b4cc3e62be4457dbb9a8387a175ac712b2'}, -- AM Temples to Ankh-Morpork(Street of Small Gods outside two temples)
{1, 853, 949, 869, 959, 'e9c7e3e6a0cf1e03e8814fb21b99890d1e52cdc0'}, -- Ankh-Morpork to AM Temples(entrance hall of the temple of Sek)
{10, 385, 40, 440, 73, '5aa065b4cc3e62be4457dbb9a8387a175ac712b2'}, -- AM Temples to Ankh-Morpork(Street of Small Gods outside two temples)
{1, 964, 852, 978, 861, '1dda78b812eeeefb0e238b80f71b8232a9bafd8f'}, -- Ankh-Morpork to AM Temples(High Altar of Hat)
{10, 962, 69, 1020, 91, '691eb08a92cc1edcd49eaf51dc7437d0307ff8bf'}, -- AM Temples to Ankh-Morpork(junction of the Street of Small Gods and Market Street)
{1, 1018, 800, 1060, 812, '8dbd4a2c9fc04df4be1055d5a4cb3b90695cdec4'}, -- Ankh-Morpork to AM Temples(entrance to the temple of Sandelfon)
{10, 800, 342, 846, 376, '0d9c2b531ac0d0cb48aaceb703996af57ecbf81a'}, -- AM Temples to Ankh-Morpork(Street of Small Gods, at the entrance to Sandelfon's temple)
{1, 824, 925, 834, 936, 'e59f1c8f73806c54b29c2823bd7f8de936647fe7'}, -- Ankh-Morpork to Temple of Small Gods(entrance to the Temple of Blind Io)
{9, 143, 110, 303, 138, 'be5c8e135faaeedf0221eac09dd1a792034c668b'}, -- Temple of Small Gods to Ankh-Morpork(Street of Small Gods)
{1, 810, 948, 834, 964, '0dd4f89a4a426dde74df94505e55c1e5410b0a0a'}, -- Ankh-Morpork to Temple of Small Gods(entrance hall of the Temple of Small Gods)
{1, 1103, 1046, 1156, 1056, '4609a954a57222d6f73a4fcdfc1c71f3f452cccf'}, -- Ankh-Morpork to AM Cruets(entry of the Salt Shaker)
{4, -3, 50, 59, 89, '29896335fc1c208788bda8cfc5c5106d291be9cd'}, -- AM Cruets to Ankh-Morpork(Upper Broadway, just outside the Salt Shaker)
{1, 1120, 1057, 1145, 1070, 'ebfd03de5885e8a24426811f1cabca043f5d81f5'}, -- Ankh-Morpork to AM Cruets(entrance to the Pepper Pot)
{4, 1, 246, 59, 293, '21b8eb32b109648d09890d7a7dd86f2914ed0727'}, -- AM Cruets to Ankh-Morpork(Upper Broadway outside the Pepper Pot)
{1, 1119, 963, 1144, 978, 'b1e8ee373198b93b9ffac4ce6e42867a656fd2df'}, -- Ankh-Morpork to AM Buildings(hallway)
{3, 1038, 343, 1089, 388, '4b794b597faa991297e092998f3e97f353f1a17e'}, -- AM Buildings to Ankh-Morpork(Lobbin Clout)
{1, 1064, 910, 1085, 926, '80e0a84b2e5202d4d08641d2636398e0af7ad375'}, -- Ankh-Morpork to AM Buildings(courtyard)
{3, 639, 335, 696, 383, '0daa82e9067a42f434d0ed2d83537bc1f61a655c'}, -- AM Buildings to Ankh-Morpork(gravel path)
{1, 640, 343, 668, 360, 'cbabc11545f4103d31c41c0a52f6b580cd7be608'}, -- Ankh-Morpork to AM Buildings(Council entrance)
{3, 179, 9, 228, 54, 'd84b9535541dffb1f006ffd7e4d4ce3ab73c0a9d'}, -- AM Buildings to Ankh-Morpork(Speedwell Street outside the Ankh-Morpork Council)
{1, 207, 621, 308, 669, '01bbd8b887e71314d8e358cbaf4f585391206bc4'}, -- Ankh-Morpork to Shades Maze(maze entrance)
{8, -68, 78, 29, 237, '874493e57dff36b786fa5dcf7d82208560872561'}, -- Shades Maze to Ankh-Morpork(Troll's Head)
{1, 853, 783, 905, 804, 'b54981c3e9f05054b495e1141e15842eeee473fe'}, -- Ankh-Morpork to AM Buildings(foyer in the Patrician's Palace)
{3, 173, 376, 229, 424, '7266a8730ad548ad8c0b8bb43ae32d52a231dbd0'}, -- AM Buildings to Ankh-Morpork(Turnwise Broadway)
{1, 711, 660, 726, 672, 'ccde479add4c4ea5901cfd160748d18ee376d01a'}, -- Ankh-Morpork to AM Isle of Gods(entrance to Lord Wynkin's Men)
{7, 577, 179, 614, 236, '763068db739761ab8ce5c518a44e733d08db6c1e'}, -- AM Isle of Gods to Ankh-Morpork(Lower Broadway)
{7, 435, 185, 482, 228, '64ae3038cb91148fbb06b102d29c970f895df92d'}, -- AM Isle of Gods to Ankh-Morpork(Brewer Street)
{1, 737, 640, 759, 662, '3a30691d817ee98da64b5596eed811793548a5e6'}, -- Ankh-Morpork to AM Isle of Gods(southwest corner of Thespians' Yard)
{1, 754, 665, 773, 680, '263f6318cfde1443408b472244f6ad1edb7755b4'}, -- Ankh-Morpork to AM Isle of Gods(entrance to the Royal Art Museum)
{7, 258, 550, 327, 618, 'bb6730c2bcf2dc106d19da11402641ef4e15ec10'}, -- AM Isle of Gods to Ankh-Morpork(Lower Broadway)
{1, 713, 473, 735, 499, '5e27050325284b7b94f817fd6166a35c7f987bdf'}, -- Ankh-Morpork to AM Isle of Gods(Craft Court)
{7, 344, 129, 404, 185, '2859bde83502e0dee341496ea95f475b6da189eb'}, -- AM Isle of Gods to Ankh-Morpork(near the east end of Phedre Road)
{1, 697, 556, 712, 568, 'a15518d9d1956b2a92f862101578184940880993'}, -- Ankh-Morpork to AM Isle of Gods(hallway of Number One, Pseudopolis Yard)
{7, 10, 220, 101, 287, 'ad942627ee46891bebb01fd673ea9dda5d18fc96'}, -- AM Isle of Gods to Ankh-Morpork(Pseudopolis Yard)
{1, 712, 572, 726, 584, 'baeef80afb3c17d47cf12d1cb9127bdfcb1ec47d'}, -- Ankh-Morpork to AM Isle of Gods(print shop's foyer)
{1, 686, 628, 695, 635, 'e4323daefa982b5bbc15bdbe3ba57752df4c1e7d'}, -- Ankh-Morpork to Pseudopolis Watch House(northeastern part of the main hall)
{14, 45, 26, 121, 86, '23551f6704d8d8fbcfd5440a280bdcc3c681f69e'}, -- Pseudopolis Watch House to Ankh-Morpork(Pseudopolis Yard)
{1, 661, 654, 683, 665, 'e4323daefa982b5bbc15bdbe3ba57752df4c1e7d'}, -- Ankh-Morpork to Pseudopolis Watch House(northeastern part of the main hall)
{45, 169, 343, 289, 472, '4b11616f93c94e3c766bb5ad9cba3b61dcc73979'}, -- Sto Plains Region to Ankh-Morpork(north end of Short Street outside the Mended Drum)
{1, 75, 207, 126, 221, '40068f55b21d63102a10d811ad8043c74e1fbade'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, 282, 11, 331, 26, 'eebbd19883152b5441290c929eb902ab2e4a9ae1'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, 720, -3, 770, 12, '514c30926f5c212eeccd2b9d9b43c2cfc051b292'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, 1267, 279, 1323, 299, 'ad9e0e9b280042358ed40a2705515f386ac897e8'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, 1138, 1116, 1196, 1136, '6a568b66b1f84cf5b4c7963803dd3e58895c613f'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, 736, 1242, 791, 1257, 'f29e7bb015cbdbc922bd1788133f1a45eb913fab'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, 373, 1212, 431, 1234, '55e5fedda888a0901f15d61944682cc99b00d588'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, 143, 1127, 202, 1155, 'a8e36f6f39a93074a7779789ab4833f487ae7020'}, -- Ankh-Morpork to Sto Plains Region(road)
{1, -2, 904, 45, 921, '34dfa0fb3a9a726700d3b154a1cb9fef5c58d829'}, -- Ankh-Morpork to Sto Plains Region(road)
{45, 0, 865, 57, 887, 'b84d02e871489603adc153fedbf6a208536d048d'}, -- Sto Plains Region to Klatch Region(road)
{31, 1666, 1326, 1733, 1346, '4f3f368b9305a6d353b5661723d4eab0120ca5e2'}, -- Klatch Region to Sto Plains Region(Klatch Road, where it splits off toward the Morpork mountains)
{45, 134, 636, 209, 651, '8c5c560432c6ba61c7de78f224643fa805217d11'}, -- Sto Plains Region to Death's Domain(Edge of Reality)
{22, 52, 33, 154, 59, '1b4fccc2e9944f3f5714843a3aa2c593e8c1192b'}, -- Death's Domain to Sto Plains Region(clearing)
{45, 383, 429, 431, 476, '326449a847b703d051fd8efcc2717087a2de429e'}, -- Sto Plains Region to Sto-Lat(centre of the Royal Market)
{39, 80, 199, 100, 214, '4b11616f93c94e3c766bb5ad9cba3b61dcc73979'}, -- Sto-Lat to Ankh-Morpork(north end of Short Street outside the Mended Drum)
{39, 115, 205, 175, 225, '22a5bfab84412168732c9d40c4feebeedc8714ea'}, -- Sto-Lat to Sto Plains Region(road)
{39, 531, 172, 587, 192, 'b01d100521beb946589a12b70704026f9d1be58e'}, -- Sto-Lat to Sto Plains Region(road)
{45, 1431, 125, 1489, 198, '6da544682de2741198f30d513a49337ef547fce2'}, -- Sto Plains Region to Ramtops Regions(Ramtops road)
{38, 246, 174, 320, 207, 'e31337ed58ac5bdf7352c52fc4ded9ca0188706d'}, -- Ramtops Regions to Sto Plains Region(intersection of Pseudopolis road and the Ramtops road)
{38, 213, 224, 270, 311, 'e31337ed58ac5bdf7352c52fc4ded9ca0188706d'}, -- Ramtops Regions to Sto Plains Region(intersection of Pseudopolis road and the Ramtops road)
{38, 241, 449, 311, 478, '9dfd44df4a880d3e75ef338aca18d89676ed397f'}, -- Ramtops Regions to Sto Plains Region(road running through Hillshire)
{45, 1080, 966, 1152, 1008, '08aef95efe17843d4162a377dbc57aff0d56049d'}, -- Sto Plains Region to Uberwald Region(road)
{46, 98, -10, 183, 28, '450e4c7eacd4f793ac2416d1bc310ff4e25bfd24'}, -- Uberwald Region to Sto Plains Region(road)
{46, 254, -8, 307, 26, '0e053d4d828f009685ce5ebab09b9af68f9eea95'}, -- Uberwald Region to Ramtops Regions(Chalk road)
{38, 1668, 702, 1775, 746, '1a28b1cd72e6781a6051a38fdb65d7b55ce51930'}, -- Ramtops Regions to Uberwald Region(Kings road)
{46, 643, 217, 678, 239, 'ff7aaf299c0b07b2f456918f2053841cb02916a2'}, -- Uberwald Region to Monks of Cool(outside the Cool Temple)
{34, 47, 179, 121, 208, '254c4c72a2cd43d33b780fead4be70afe719f72b'}, -- Monks of Cool to Uberwald Region(intersection of Kings and Smarl River roads)
{46, 875, 568, 931, 617, '319a201d17677fe960760d92032eb9783be7bf85'}, -- Uberwald Region to Magpyr's Castle(dangerous road)
{15, 258, 472, 330, 492, '3eee89b825899a1bf92a487123c33989ddf47ff2'}, -- Magpyr's Castle to Uberwald Region(forest trail)
{31, 1094, 891, 1172, 962, '5b7c6cc0ad1ed4b5250a681a390918afe25835a2'}, -- Klatch Region to Ephebe(Impartiality Avenue)
{31, 1108, 964, 1159, 975, '5b7c6cc0ad1ed4b5250a681a390918afe25835a2'}, -- Klatch Region to Ephebe(Impartiality Avenue)
{25, 826, 396, 856, 436, 'e03214b1f9cd95492116a08eb9fab6d4144b5ef9'}, -- Ephebe to Klatch Region(road through a vineyard)
{25, 822, 610, 849, 650, 'a8bca8826fff1ca24fc7262e79bcfa495347e404'}, -- Ephebe to Klatch Region(Klatch Road)
{25, 765, 661, 843, 715, '64ee40a06178cbddb80935725cb463e2e21770b5'}, -- Ephebe to Klatchian Farmsteads(service entrance to the Chronides farmstead)
{48, 484, 205, 543, 254, 'ae13c6c35e4299c06c6b566593b911c0292ea29e'}, -- Klatchian Farmsteads to Klatch Region(intersection)
{31, 1147, 1023, 1196, 1042, '64ee40a06178cbddb80935725cb463e2e21770b5'}, -- Klatch Region to Klatchian Farmsteads(service entrance to the Chronides farmstead)
{31, 1139, 992, 1149, 1003, '64ee40a06178cbddb80935725cb463e2e21770b5'}, -- Klatch Region to Klatchian Farmsteads(service entrance to the Chronides farmstead)
{25, 608, 562, 659, 586, '71d9e658a4b55ab410f87f71892a2dcc26f32945'}, -- Ephebe to Klatch Region(road through a tomato crop)
{25, 451, 534, 490, 558, '6147f2934c5e7140d2a38f7207f6769639c1b9a6'}, -- Ephebe to Klatch Region(road through a tomato crop)
{25, 303, 470, 330, 489, '6c2930388a2f4e07a1faa712105ac5be47cca319'}, -- Ephebe to Klatch Region(Klatch Road)
{25, 14, 57, 142, 155, '513b9fb194a1d6249d5a11f9b16858c7e09c9c8e'}, -- Ephebe to Klatch Region(intersection)
{25, 269, 496, 300, 525, 'd7be1eae6cfe2c432a78e88919fac95a443f2c87'}, -- Ephebe to Klatch Region(intersection)
{25, 403, 595, 433, 629, '43869b06780143cfb93e4481a975f29e0802219c'}, -- Ephebe to Klatch Region(intersection)
{25, 535, 641, 602, 712, '050b828e9c5ea01f47a0e16ffb6f6b82e3dc23a1'}, -- Ephebe to Klatch Region(intersection)
{25, 667, 726, 728, 789, 'd384d318f55a285cae89b1253988bdf27754e855'}, -- Ephebe to Klatch Region(intersection)
{25, 522, 795, 592, 867, '02ebcb8f11ba90b70b0bed06ac66e6bd85008b9d'}, -- Ephebe to Klatch Region(intersection)
{26, 234, 229, 268, 244, 'bb138a9349adf67346cc5819aa31c990084ef2f6'}, -- Ephebe Underdocks to Ephebe(abandoned stall)
{23, 0, -3, 110, 114, '3829738a5a4426950321d7307a8165c159a96466'}, -- Djelibeybi to Klatch Region(Klatchian Foreign Legion outpost campfire)
{31, 948, 690, 966, 729, 'bdf61f65e0b9cf7d87e50213d1f7fc2d3db02cd2'}, -- Klatch Region to Djelibeybi(Ptrip-Ptrap bridge)
{23, 387, 583, 490, 646, '513b9fb194a1d6249d5a11f9b16858c7e09c9c8e'}, -- Djelibeybi to Klatch Region(intersection)
{31, 899, 748, 917, 787, '3abe3eeb907d8747da3d929811336fb722520a45'}, -- Klatch Region to Djelibeybi(Djelibeybi road)
{23, 116, 372, 164, 387, '22329542c2f3ab37db69ad5fab92156e73884f58'}, -- Djelibeybi to Klatch Region(grassy plain)
{31, 791, 755, 828, 778, 'dd9f47f4c56942524327bfe024bd84ad7e387ce7'}, -- Klatch Region to Klatchian Farmsteads(eastern entrance to a farmyard)
{48, 142, 131, 178, 161, '977681e1f93bd661e9ea74902ab23bb6e8b3c2a7'}, -- Klatchian Farmsteads to Klatch Region(grassy plain)
{31, 689, 752, 734, 767, 'cae6eb9b556284aada2249afcb7ffa1c21432074'}, -- Klatch Region to Hashishim Caves(tunnel)
{30, 231, 73, 280, 109, 'eccde9f346a35d85fa0f201dbc0a5585084e4a9b'}, -- Hashishim Caves to Klatch Region(plains)
{31, 1022, 757, 1110, 787, '1a98ad51da8a7dc72174ca33e86c4c4c04335181'}, -- Klatch Region to Djelibeybi(Harbour Road)
{31, 999, 746, 1015, 781, 'bc27e8c0f9d277d4886783004169ccf2477d72fd'}, -- Klatch Region to Djelibeybi(Djelibeybi road)
{31, 938, 813, 981, 831, '70f584318b304ee7b32f573035a880b4b46065f1'}, -- Klatch Region to Djelibeybi(Djelibeybi road)
{31, 921, 737, 994, 809, '4ed9b9006731e04ade1ed9c34d41861fbe8ae1b1'}, -- Klatch Region to Djelibeybi(junction of the Avenue of the Pharaohs, Market Street and Phoenix Road)
{24, 91, 194, 156, 225, '5b08a5671f4e61511110b2c6437ccec6cdd32461'}, -- IIL - DJB Wizards to Djelibeybi(Avenue of the Pharaohs at the entrance of an official building)
{23, 446, 476, 480, 485, 'b85065b07a1c156d19f7b552397b32844bb7335c'}, -- Djelibeybi to IIL - DJB Wizards(courtyard of the Djelibeybi Institute of Illusory Learning)
{23, 410, 461, 429, 476, 'd6f74be9039ab49d367c5904915aac9c120e1a8a'}, -- Djelibeybi to Djelibeybi(lobby of the Fez Club)
{23, 473, 268, 482, 275, '6f668a720914be85b0abb5da849e99749d7d0ea3'}, -- Djelibeybi to Djelibeybi(entrance portal of the Djelian Guard)
{23, 543, 263, 564, 277, '075b7543348543c389d39ccd38247a59d00ac98a'}, -- Djelibeybi to Djelibeybi(foyer)
{23, 486, 262, 500, 270, '5edcaa3035201bee13618c95af3d8e8399405c33'}, -- Djelibeybi to Djelibeybi(elegant sandstone room)
{23, 407, 240, 443, 250, '21a16612007f335a629a14e7d844135fe9d505c9'}, -- Djelibeybi to Djelibeybi(entrance hall of the palace)
{23, 454, 299, 472, 319, '2926cb5dd1277de9a0c2162b2e5e792de4f63805'}, -- Djelibeybi to Djelibeybi(barracks Guard house and main entrance)
{27, 437, 267, 463, 274, 'ea8960ad9869d9c40043577dca5e3fd090efd9f6'}, -- Genua to Genua(garden outside a stately white building)
{27, 493, 434, 500, 449, 'b5a956c94403920a1ad6c0c935343c10549d76ec'}, -- Genua to Genua(temple of Gapp)
{27, 143, 218, 169, 233, 'a1755a2f5b92db6af5feb15f06879896aff8a44c'}, -- Genua to Genua(comfortable office)
{27, 197, 282, 240, 290, '3b8a246e6a4c345fc2f5c88da96383fee307927c'}, -- Genua to Genua(entrance to the barracks)
{27, 324, 378, 356, 388, 'd572da8982764dd019315e09c4fc75b93bbf0bf6'}, -- Genua to Genua(Diamond City Casino foyer)
{29, 283, 9, 411, 146, '762a6133bd35110a4ebbed7305685b677c1357ca'}, -- GRFLX Caves to Sto Plains Region(trail through a forest)
{33, 273, 225, 330, 261, 'd8e35a2851b29a32a08546d85a2e955b27caa0b4'}, -- Mano Rossa to Genua(Dauphin Street, east of Okra Avenue)
{27, 410, 176, 435, 192, '2e07bf34ece29ebd366ed3c39f1d84da87bcd999'}, -- Genua to Mano Rossa(front garden)
{35, 24, 55, 65, 63, '8c8f53eb3b312ac3746341a6700703a98234ce69'}, -- Netherworld to Djelibeybi(Avenue of the Pharaohs at <weapon>roads)
{39, 388, 327, 438, 353, 'c1d633be3697cdef18780c5cbca5f10354b7300c'}, -- Sto-Lat to Cabbage Warehouse(warehouse loading dock)
{41, 2, 73, 40, 112, '73e6b79389e6f6d66b8653b6c30f425f96a84a34'}, -- Cabbage Warehouse to Sto-Lat(nice alley south of Hat's temple)
{39, 297, 258, 330, 272, '572f3c54b5dece1f8fd35b74eb87f99482004a7d'}, -- Sto-Lat to Academy of Artificers(Academy of Artificers)
{40, 21, 36, 73, 62, '267190649b1394ef19b4a92aa4a8b552c0fed383'}, -- Academy of Artificers to Sto-Lat(King's Road)
{44, 182, 239, 228, 254, '0165a796985323b12daaeaf120ef5af2ffcd4a0d'}, -- Sprite Caves to Ramtops Regions(next to a waterfall)
{38, 1827, 421, 1865, 428, 'ab65749bc71efdbb979b04ba3d853a2810fea296'}, -- Ramtops Regions to Sprite Caves(underground cavern)
{47, 151, 4832, 181, 4842, 'd67e7fc940fa14ae6356389ec1c96cc27ad81391'}, -- UU Library to Unseen University(quadrangle)
{17, 991, 700, 1030, 713, 'b92fc00e0eaaf546f6eadb07eadbd688a9dd9d18'}, -- Bes Pelargic to BP Buildings(north entrance to a friendly building)
{18, 123, 321, 157, 348, '8ba9f22eca5612ba8a6f1c61e46cb2b24b88c7bc'}, -- BP Buildings to Bes Pelargic(Hook Street, near the fish markets)
{17, 958, 576, 978, 600, '9665e368ca73b69741b811e7fbfd3a121e64ca62'}, -- Bes Pelargic to BP Buildings(the entrance to the Language Institute)
{18, 404, 195, 454, 231, '874f97223b066fc318289ba5b4a05bcd83e14213'}, -- BP Buildings to Bes Pelargic(Serpentine Way, outside the entrance to the Language Institute)
{17, 1177, 329, 1243, 364, 'bd559090589e83c751d232b9886295801406eb02'}, -- Bes Pelargic to BP Buildings(Tier of Seven Hundred Corridors)
{18, 4, 29, 75, 63, '8c61f55c2d16d807ab1127260e1ce35a90a5d1d2'}, -- BP Buildings to Bes Pelargic(small path leading to a tall tower)
{17, 485, 672, 514, 685, 'b72ab8ab69eb114374405541cf774097c0badc36'}, -- Bes Pelargic to BP Buildings(octagon court)
{18, 443, 447, 497, 468, '2a7450e50d956e8f7277d037031c0695e9a6f125'}, -- BP Buildings to Bes Pelargic(end of the Street of the Smiling Dog)
{17, 176, 665, 225, 690, '5e4ba01e54fbdacb3a68265022a1ee48e341e75f'}, -- Bes Pelargic to BP Estates(winding path through the Hong orchard)
{19, 399, 165, 443, 187, '57c2105bb91dfae518055fd366e871a06d1f1d7b'}, -- BP Estates to Bes Pelargic(Onetwolong Avenue at the entrance to the Hong Estate)
{17, 438, 528, 487, 552, '945dc5c345a9fc1e6cc9897c1478e9e11c181858'}, -- Bes Pelargic to BP Estates(Golden Gate at the entrance to the Fang Estate)
{19, 552, 499, 609, 513, '099a24c0e097ac3b0726b77cf5c8ef25e5df6198'}, -- BP Estates to Bes Pelargic(plateau high up on Tora Hill)
{17, 1176, 153, 1230, 171, 'c5942b3d5ed30254da4302028b763b7e26be458a'}, -- Bes Pelargic to Ninja Guild(entrance)
{52, 92, -4, 123, 34, '1fd3217446fe4825f97112f9dd435e9178725731'}, -- Ninja Guild to Bes Pelargic(Silk Lane)
{17, 529, 2, 625, 28, '88f27c396e45db66c0a7d6f305ab7d7ffeb6d9c3'}, -- Bes Pelargic to BP Estates(gateway to the McSweeney Estate)
{19, 914, 638, 969, 657, '0cd3913c97954dece80b36d2bf4d82eec22ad2dd'}, -- BP Estates to Bes Pelargic(Sum Bing Road)
{17, 25, 104, 73, 160, 'f02bd3eaea000ca979a6b3c623d342ff4d9159fa'}, -- Bes Pelargic to BP Estates(dock at the base of the Tang Island cliffs)
{19, 94, 165, 185, 182, '880661773b394f65e568b96af2a5a699624a43af'}, -- BP Estates to Bes Pelargic(end of the Tang pier)
{17, 659, 337, 711, 362, '978c286140d7e459656feabdf53a9d602919e464'}, -- Bes Pelargic to BP Estates(grand entrance hall of the Sung Estate)
{19, 810, 79, 934, 119, 'ec699e021b418606cbf0436f246b4caab0884f82'}, -- BP Estates to Bes Pelargic(Albin Lane outside of the main entrance to the Sung Estate)
{19, 882, 167, 957, 183, '1a8cfd1c6c3c15a46dcb0279f8ddc96f18c67a84'}, -- BP Estates to Bes Pelargic(Pearl Path, outside the entrance to the Sung Estate)
{20, 15, 492, 72, 523, 'ce2dbd4f3e8282ff88de10f99942f8c1836c23c8'}, -- BP Wizards to Bes Pelargic(cosy second-hand bookshop)
{17, 598, 254, 604, 260, '69689afecf305db4bc84a7dfc9dac90a42a16d6e'}, -- Bes Pelargic to BP Wizards(tiny room in a pocket just off the edge of L-space)
{1, 136, 624, 159, 634, '410a73c0b58f8816f56b0ba4226768a380dd196f'}, -- Ankh-Morpork to AM Temples(fish shop)
{10, 56, 104, 116, 139, 'bd8f86c94070c5fca1a0eaadb41fd390848afb93'}, -- AM Temples to Ankh-Morpork(Cockbill Street)
{1, 876, 847, 907, 872, 'd5b54f04904f81f73dbec4da0bd5d263b3910d77'}, -- Ankh-Morpork to AM Warriors(lobby of the Palace Guard)
{13, 149, 71, 170, 91, '1c08ecf555038e329c15c07650d1a852907c6e81'}, -- AM Warriors to Ankh-Morpork(Patrician's Palace gate)
{13, 179, 100, 240, 153, '1c08ecf555038e329c15c07650d1a852907c6e81'}, -- AM Warriors to Ankh-Morpork(Patrician's Palace gate)
{1, 1269, 767, 1296, 814, '22cb1754a73395759e82a1dbe8c51dd8be5b9401'}, -- Ankh-Morpork to AM Warriors(Weapon Masters' Court's bar)
{1, 1243, 793, 1274, 815, '22cb1754a73395759e82a1dbe8c51dd8be5b9401'}, -- Ankh-Morpork to AM Warriors(Weapon Masters' Court's bar)
{13, 372, 63, 429, 95, '0eea895f870e1114e6f04a93ec624baf4cc37555'}, -- AM Warriors to Ankh-Morpork(Vagabond Street, outside a pub)
{38, 1641, 283, 1673, 297, '52c70f41906ee625fc59300631e4f59483bda867'}, -- Ramtops Regions to Slippery Hollow(start of a narrow road)
{54, 203, 226, 237, 242, 'b3bde6882b7f536cfebfebc2790f0c5c12fe8a4f'}, -- Slippery Hollow to Ramtops Regions(Slippery Hollow road)
}
-- **********************************************************************
-- * Map File Names/Core Locations *
-- **********************************************************************
-- The file names and the "friendly title" for the titlewindow of the map, for each location
-- Also contains the "grid size" - a value to move the map by automatically for an average 1 room size (guesstimate tracking)
-- And finally a default "centre-point" for those maps
sQuowMapfiles = {
[1] = { "am.png", "Ankh-Morpork", 14, 14, 718, 802 },
[2] = { "am_assassins.png", "AM Assassins", 28, 28, 457, 61 },
[3] = { "am_buildings.png", "AM Buildings", 25, 25, 208, 76 },
[4] = { "am_cruets.png", "AM Cruets", 24, 24, 300, 69 },
[5] = { "am_docks.png", "AM Docks", 14, 14, 174, 216 },
[6] = { "am_guilds.png", "AM Guilds", 28, 28, 487, 245 },
[7] = { "am_isle_gods.png", "AM Isle of Gods", 24, 24, 342, 587 },
[8] = { "am_shades.png", "Shades Maze", 79, 79, 48, 174 },
[9] = { "am_smallgods.png", "Temple of Small Gods", 24, 24, 221, 224 },
[10] = { "am_temples.png", "AM Temples", 24, 24, 575, 419 },
[11] = { "am_thieves.png", "AM Thieves", 28, 28, 431, 300 },
[12] = { "am_uu.png", "Unseen University", 28, 28, 166, 393 },
[13] = { "am_warriors.png", "AM Warriors", 32, 25, 135, 104 },
[14] = { "am_watch_house.png", "Pseudopolis Watch House", 24, 24, 88, 104 },
[15] = { "magpyr.png", "Magpyr's Castle", 20, 20, 141, 440 },
[16] = { "bois.png", "Bois", 14, 14, 239, 169 },
[17] = { "bp.png", "Bes Pelargic", 14, 14, 1070, 748 },
[18] = { "bp_buildings.png", "BP Buildings", 24, 24, 428, 177},
[19] = { "bp_estates.png", "BP Estates", 14, 14, 540, 506 },
[20] = { "bp_wizards.png", "BP Wizards", 20, 20, 101, 517 },
[21] = { "brown_islands.png", "Brown Islands", 28, 28, 105, 101 },
[22] = { "deaths_domain.png", "Death's Domain", 28, 28, 98, 86 },
[23] = { "djb.png", "Djelibeybi", 14, 14, 438, 369 },
[24] = { "djb_wizards.png", "IIL - DJB Wizards", 28, 28, 210, 210 },
[25] = { "ephebe.png", "Ephebe", 14, 14, 610, 351 },
[26] = { "ephebe_under.png", "Ephebe Underdocks", 14, 14, 247, 285 },
[27] = { "genua.png", "Genua", 14, 14, 470, 242 },
[28] = { "genua_sewers.png", "Genua Sewers", 21, 21, 405, 312 },
[29] = { "grflx.png", "GRFLX Caves", 20, 20, 303, 222 },
[30] = { "hashishim_caves.png", "Hashishim Caves", 28, 28, 258, 132 },
[31] = { "klatch.png", "Klatch Region", 14, 14, 724, 515 },
[32] = { "lancre_castle.png", "Lancre Region", 14, 14, 285, 33 },
[33] = { "mano_rossa.png", "Mano Rossa", 28, 28, 298, 202 },
[34] = { "monks_cool.png", "Monks of Cool", 14, 14, 113, 170 },
[35] = { "netherworld.png", "Netherworld", 14, 14, 42, 75 },
[36] = { "oasis.png", "Oasis", 28, 28, 179, 177 },
[37] = { "pumpkin_town.png", "Pumpkin Town", 48, 48, 375, 194 },
[38] = { "ramtops.png", "Ramtops Regions", 14, 14, 1056, 223 },
[39] = { "sl.png", "Sto-Lat", 14, 14, 367, 222 },
[40] = { "sl_aoa.png", "Academy of Artificers", 25, 25, 47, 87 },
[41] = { "sl_cabbages.png", "Cabbage Warehouse", 28, 28, 60, 92 },
[42] = { "sl_library.png", "AoA Library", 57, 57, 220, 411 },
[43] = { "sl_sewers.png", "Sto-Lat Sewers", 14, 14, 162, 204 },
[44] = { "sprite_caves.png", "Sprite Caves", 14, 14, 113, 182 },
[45] = { "sto_plains.png", "Sto Plains Region", 14, 14, 752, 390 },
[46] = { "uberwald.png", "Uberwald Region", 14, 14, 673, 643 },
[47] = { "uu_library_full.png", "UU Library", 30, 30, 165, 4810 },
[48] = { "farmsteads.png", "Klatchian Farmsteads", 28, 28, 445, 171 },
[49] = { "ctf_arena.png", "CTF Arena", 48, 48, 307, 283 },
[50] = { "pk_arena.png", "PK Arena", 30, 30, 155, 331 },
[51] = { "am_postoffice.png", "AM Post Office", 28, 28, 156, 69 },
[52] = { "bp_ninjas.png", "Ninja Guild", 28, 28, 109, 56 },
[53] = { "tshop.png", "The Travelling Shop", 28, 28, 355, 315 },
[54] = { "slippery_hollow.png", "Slippery Hollow", 14, 14, 215, 123 },
}
-- Lookup table to quickly convert directions to pixel-shift directions
sQuowTrackMoves = {
["n"] = { 0, -1 },
["ne"] = { 1, -1 },
["e"] = { 1, 0 },
["se"] = { 1, 1 },
["s"] = { 0, 1 },
["sw"] = { -1, 1 },
["w"] = { -1, 0 },
["nw"] = { -1, -1 },
["north"] = { 0, -1 },
["northeast"] = { 1, -1 },
["east"] = { 1, 0 },
["southeast"] = { 1, 1 },
["south"] = { 0, 1 },
["southwest"] = { -1, 1 },
["west"] = { -1, 0 },
["northwest"] = { -1, -1 },
-- Left/right etc. need to be treated differently
["lt"] = { 0, 0 },
["left"] = { 0, 0 },
["rt"] = { 0, 0 },
["right"] = { 0, 0 },
["fw"] = { 0, 0 },
["forward"] = { 0, 0 },
["bw"] = { 0, 0 },
["backward"] = { 0, 0 },
-- Shades direction specials
["1"] = { 6, 6 },
["2"] = { 6, 6 },
["3"] = { 6, 6 },
["4"] = { 6, 6 },
["5"] = { 6, 6 },
["6"] = { 6, 6 },
["7"] = { 6, 6 },
["8"] = { 6, 6 },
}
-- Short-hand conversion of directions
sMovementShort = {
["north"] = "n",
["northeast"] = "ne",
["east"] = "e",
["southeast"] = "se",
["south"] = "s",
["southwest"] = "sw",
["west"] = "w",
["northwest"] = "nw",
["n"] = "n",
["ne"] = "ne",
["e"] = "e",
["se"] = "se",
["s"] = "s",
["sw"] = "sw",
["w"] = "w",
["nw"] = "nw",
["up"] = "u",
["down"] = "d",
["u"] = "u",
["d"] = "d",
}
-- Reverse directions
sReverseMove = {
["n"] = "s",
["ne"] = "sw",
["e"] = "w",
["se"] = "nw",
["s"] = "n",
["sw"] = "ne",
["w"] = "e",
["nw"] = "se",
["north"] = "s",
["northeast"] = "sw",
["east"] = "w",
["southeast"] = "nw",
["south"] = "n",
["southwest"] = "ne",
["west"] = "e",
["northwest"] = "se",
["enter stall"] = "out",
["enter tent"] = "out",
["walk n"] = "walk s",
["walk ne"] = "walk sw",
["walk e"] = "walk w",
["walk se"] = "walk nw",
["walk s"] = "walk n",
["walk sw"] = "walk ne",
["walk w"] = "walk e",
["walk nw"] = "walk se",
["down"] = "u",
["up"] = "d",
["d"] = "u",
["u"] = "d",
}
-- **********************************************************************
-- * Remaining Key Variables *
-- **********************************************************************
sUserFont = GetVariable("sUserFont")
if (sUserFont == nil) then
sUserFont = "FixedSys"
end
iFontSize = tonumber(GetVariable("iFontSize"))
if (iFontSize == nil) then
iFontSize = 8
end
bShowDiscDate = true
if (GetVariable("bShowDiscDate") == "false") then
bShowDiscDate = false
end
bShowCommsTabs = true
iTopCommsWindow = 0
if (GetVariable("bShowCommsTabs") == "false") then
bShowCommsTabs = false
end
bShowHPNotifications = false
if (GetVariable("bShowHPNotifications") == "true") then
bShowHPNotifications = true
end
bShowXPNotifications = false
if (GetVariable("bShowXPNotifications") == "true") then
bShowXPNotifications = true
end
bOptimisedCombatTriggers = false
if (GetVariable("bOptimisedCombatTriggers") == "true") then
bOptimisedCombatTriggers = true
end
-- Whether we're currently "temporarily hiding in terrains" or not;
bMinimapHidden = false
bMinimapTempHidden = false
-- Auto-Hide in Terrain
bHideOnTerrain = true
if (GetVariable("bHideOnTerrain") == "false") then
bHideOnTerrain = false
end
-- Set to true to have the minimap attempt to auto-hide when in (limited, recognised) terrains, and show again when not
-- Draw orbs in the UU library
bDrawOrbs = true
if (GetVariable("bDrawOrbs") == "false") then
bDrawOrbs = false
end
-- Set to true to draw circles in the UU library when escaped spells/orbs are detected
-- Do not move map based on "predictions"
bPredictiveMoves = false
if (GetVariable("bPredictiveMoves") == "true") then
bPredictiveMoves = true
end
-- Set to false to prevent the minimap ever moving in any room not in the database
-- Show "ghost" of where your character really is when spamming ahead
bShowGhost = true
if (GetVariable("bShowGhost") == "false") then
bShowGhost = false
end
-- Set to false to prevent the ghost being drawn
-- Hide Kefka's map and draw a skeleton mode instead
bDrawSkeletonMode = false
if (GetVariable("bDrawSkeletonMode") == "true") then
bDrawSkeletonMode = true
end
-- Stack the health bars vertically or not
bVitalStacking = true
if (GetVariable("bVitalStacking") == "false") then
bVitalStacking = false
end
-- Ascii map Hide MUD output
bAsciiMapOmitted = false
if (GetVariable("bAsciiMapOmitted") == "true") then
bAsciiMapOmitted = true
end
-- Ascii auto-show terrains
bAutoShowHideAscii = false
if (GetVariable("bAutoShowHideAscii") == "true") then
bAutoShowHideAscii = true
end
-- Minimap window brightness
iMinimapBrightness = tonumber(GetVariable("iMinimapBrightness"))
if (iMinimapBrightness == nil) then
iMinimapBrightness = 100
end
if (iMinimapBrightness < 50) then
iMinimapBrightness = 50
end
-- Old special handler tests, do not use - can cause problems
bHandlerSM = false
if (GetVariable("bHandlerSM") == "true") then
bHandlerSM = true
end
bHandlerLib = false
if (GetVariable("bHandlerLib") == "true") then
bHandlerLib = true
end
bDebugMode = false
if (GetVariable("bDebugMode") == "true") then
bDebugMode = true
end
bGPThresholdMet = false
bPlayGPNotification = false
if (GetVariable("bPlayGPNotification") == "true") then
bPlayGPNotification = true
end
sGPNotificationFile = GetVariable("sGPNotificationFile")
if (sGPNotificationFile == nil) then
sGPNotificationFile = sQuowMapPath .. "incoming.wav"
end
-- Shield break sounds
-- Pull up user-saved variables, look for errors, set defaults etc.
iCurMap = tonumber(GetVariable("iCurMap"))
if (iCurMap == nil) then
iCurMap = 0
end
sCurrentMap = ""
sLoadedMap = ""
if (sQuowMapfiles[iCurMap] ~= nil) then
sCurrentMap = sQuowMapfiles[iCurMap][1]
else
iCurMap = 0
end
sOldMap = ""
iCharLocMap = 0
iOldMap = tonumber(GetVariable("iOldMap"))
if (iOldMap == nil) then
iOldMap = iCurMap
end
iOldMX = tonumber(GetVariable("iOldMX"))
iOldMY = tonumber(GetVariable("iOldMY"))
sLastDir = GetVariable("sLastDir")
sOldDir = ""
iMyX = tonumber(GetVariable("iMyX"))
iMyY = tonumber(GetVariable("iMyY"))
sPreviousRoomID = ""
bLSpaceDepths = false
sCurrentRoomID = GetVariable("sCurrentRoomID")
if (sCurrentRoomID == nil) then
sCurrentRoomID = ""
end
sClickedRoomID = GetVariable("sClickedRoomID")
if (sClickedRoomID == nil) then
sClickedRoomID = ""
end
if (sCurrentMap == nil) then
sCurrentMap = ""
end
if (sLastDir == nil) then
sLastDir = "n"
end
if (iMyX == nil) then
iMyX = 0
end
if (iMyY == nil) then
iMyY = 0
end
if (iOldMX == nil) then
iOldMX = 0
end
if (iOldMY == nil) then
iOldMY = 0
end
sThisRealRoomTitle = ""
sThisRoomTitle = ""
iTimeSinceLastMove = 0
-- Table used to store movements currently queued
--sMoveQueue = {}
iMapShiftQueue = {}
sFutureRoomID = ""
-- **********************************************************************
-- * Core Code Below *
-- **********************************************************************
-- Only used when in Creation mode, to guesstimate reverse directions where appropriate, and dismiss when not
function DirectionConvert(sTempDir)
sConvertDir = sTempDir:match'^%s*(.*%S)' or ''
sConvertDir = string.lower(sConvertDir)
if (sMovementShort[sConvertDir] ~= nil) then
sConvertDir = sMovementShort[sConvertDir]
end
if (sConvertDir == "up") then
sConvertDir = "u"
elseif (sConvertDir == "down") then
sConvertDir = "d"
elseif (sConvertDir == "journey north") then
sConvertDir = "journey n"
elseif (sConvertDir == "journey northeast") then
sConvertDir = "journey ne"
elseif (sConvertDir == "journey east") then
sConvertDir = "journey e"
elseif (sConvertDir == "journey southeast") then
sConvertDir = "journey se"
elseif (sConvertDir == "journey south") then
sConvertDir = "journey s"
elseif (sConvertDir == "journey southwest") then
sConvertDir = "journey sw"
elseif (sConvertDir == "journey west") then
sConvertDir = "journey w"
elseif (sConvertDir == "journey northwest") then
sConvertDir = "journey nw"
elseif (sConvertDir == "walk north") then
sConvertDir = "walk n"
elseif (sConvertDir == "walk northeast") then
sConvertDir = "walk ne"
elseif (sConvertDir == "walk east") then
sConvertDir = "walk e"
elseif (sConvertDir == "walk southeast") then
sConvertDir = "walk se"
elseif (sConvertDir == "walk south") then
sConvertDir = "walk s"
elseif (sConvertDir == "walk southwest") then
sConvertDir = "walk sw"
elseif (sConvertDir == "walk west") then
sConvertDir = "walk w"
elseif (sConvertDir == "walk northwest") then
sConvertDir = "walk nw"
elseif (sConvertDir == "ed") then
sConvertDir = ""
elseif (sConvertDir == "sd") then
sConvertDir = ""
elseif (sConvertDir == "g") then
sConvertDir = ""
elseif (sConvertDir == "glance") then
sConvertDir = ""
elseif (sConvertDir == "l") then
sConvertDir = ""
elseif (sConvertDir == "look") then
sConvertDir = ""
elseif (sConvertDir == "enter door") then
sConvertDir = ""
elseif (string.sub(sConvertDir, 1, 5) == "goto ") then
sConvertDir = ""
elseif (sConvertDir == "enter portal") then
sConvertDir = ""
elseif (sConvertDir == "es") then
sConvertDir = "enter stall"
elseif (sConvertDir == "et") then
sConvertDir = "enter tent"
end
return sConvertDir
end
-- Special Shades direction rememberer attempt
iShadesRoom = 0
iDestinationShadesRoom = 0
sQuowShadesDirections = {
-- Clockwise spiral from entrance ordering
[1] = {["ne"] = {"5", 2}, ["e"] = {"3", 11}, ["se"] = {"2", 16}, ["s"] = {"4", 10}, ["sw"] = {"1", 17}},
[2] = {["e"] = {"4", 3}, ["se"] = {"1", 12}, ["s"] = {"3", 11}, ["sw"] = {"2", 1}},
[3] = {["se"] = {"1", 4}, ["s"] = {"3", 12}, ["sw"] = {"4", 11}, ["w"] = {"2", 2}},
[4] = {["s"] = {"1", 5}, ["sw"] = {"4", 13}, ["w"] = {"2", 12}, ["nw"] = {"3", 3}},
[5] = {["n"] = {"6", 4}, ["s"] = {"5", 6}, ["sw"] = {"1", 14}, ["w"] = {"2", 13}, ["nw"] = {"3", 12}},
[6] = {["n"] = {"3", 5}, ["sw"] = {"1", 7}, ["w"] = {"2", 14}, ["nw"] = {"4", 13}},
[7] = {["n"] = {"3", 14}, ["ne"] = {"4", 6}, ["w"] = {"1", 8}, ["nw"] = {"2", 15}},
[8] = {["n"] = {"2", 15}, ["ne"] = {"1", 14}, ["e"] = {"4", 7}, ["nw"] = {"3", 9}},
[9] = {["n"] = {"4", 10}, ["ne"] = {"2", 16}, ["e"] = {"3", 15}, ["se"] = {"5", 8}, ["nw"] = {"1", 17}},
[10] = {["n"] = {"4", 1}, ["ne"] = {"2", 11}, ["e"] = {"6", 16}, ["se"] = {"3", 15}, ["s"] = {"5", 9}, ["w"] = {"1", 17}},
[11] = {["n"] = {"6", 2}, ["ne"] = {"7", 3}, ["e"] = {"3", 12}, ["se"] = {"5", 13}, ["s"] = {"4", 16}, ["sw"] = {"1", 10}, ["w"] = {"2", 1}},
[12] = {["n"] = {"7", 3}, ["e"] = {"6", 4}, ["se"] = {"2", 5}, ["s"] = {"3", 13}, ["sw"] = {"1", 16}, ["w"] = {"4", 11}, ["nw"] = {"5", 2}},
[13] = {["n"] = {"3", 12}, ["ne"] = {"8", 4}, ["e"] = {"1", 5}, ["se"] = {"7", 6}, ["s"] = {"6", 14}, ["sw"] = {"5", 15}, ["w"] = {"4", 16}, ["nw"] = {"2", 11}},
[14] = {["n"] = {"1", 13}, ["ne"] = {"2", 5}, ["e"] = {"6", 6}, ["s"] = {"7", 7}, ["sw"] = {"5", 8}, ["w"] = {"3", 15}, ["nw"] = {"4", 16}},
[15] = {["n"] = {"2", 16}, ["ne"] = {"3", 13}, ["e"] = {"5", 14}, ["se"] = {"7", 7}, ["s"] = {"6", 8}, ["w"] = {"1", 9}, ["nw"] = {"4", 10}},
[16] = {["n"] = {"3", 11}, ["ne"] = {"4", 12}, ["e"] = {"7", 13}, ["se"] = {"8", 14}, ["s"] = {"5", 15}, ["sw"] = {"6", 9}, ["w"] = {"2", 10}, ["nw"] = {"1", 1}},
-- Entrance
[17] = {["ne"] = {"1", 1}, ["e"] = {"3", 10}, ["se"] = {"2", 9}},
}
-- New distortion forming warning
function HandleDistortionFormed (sName, sLine, wildcards)
if (iCurMap == 47) then
ColourTell("red", sGlobalColourBlack, "Quow's Cow Bar Warning: New distortion has formed somewhere here, '")
Hyperlink ("look", "look", "", "red", sGlobalColourBlack, 0)
ColourNote("red", sGlobalColourBlack, "' to see where!")
end
end
-- New distortion forming warning
function HandleDistortionVanish (sName, sLine, wildcards)
if (iCurMap == 47) then
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar Note: Distortion has vanished, '")
Hyperlink ("look", "look", "", sGlobalColourOrange, sGlobalColourBlack, 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "' to refresh the minimap!")
end
end
-- Brief look library warning
function HandleLibraryBriefLook (sName, sLine, wildcards)
-- If we see this brief line in the main UU, switch to this map and THEN show a warning
if (sPreviousRoomID == "d67e7fc940fa14ae6356389ec1c96cc27ad81391") then
MinimapCheckSpecialID("UULibraryExit", sThisRoomTitle)
RedrawMap()
end
if (iCurMap == 47) then
ColourTell("red", sGlobalColourBlack, "Quow's Cow Bar Warning: You CANNOT see distortions in the library with brief look! Type '")
Hyperlink ("verbose look", "verbose look", "", sGlobalColourOrange, sGlobalColourBlack, 0)
ColourNote("red", sGlobalColourBlack, "' before proceeding!")
end
end
-- Handler for UU Library Orbs
function HandleLibraryOrb (sName, sLine, wildcards)
if (bDrawOrbs == true and iCurMap == 47 and (sThisRoomTitle == "Library" or sThisRoomTitle == "UULibraryExit" or sThisRoomTitle == "UULibraryGap")) then
local iSize = 5
if (wildcards[1] == "substantial sphere") then
iSize = 11
elseif (wildcards[1] == "large orb") then
iSize = 9
elseif (wildcards[1] == "moderately-sized ball") then
iSize = 7
elseif (wildcards[1] == "small point") then
iSize = 6
elseif (wildcards[1] == "tiny speck") then
iSize = 4
end
WindowCircleOp (winMinimap, 1, MINIMAP_CX - iSize, MINIMAP_CY - iSize, MINIMAP_CX + iSize, MINIMAP_CY + iSize, iGlobalColourOrange, 0, 2, iGlobalColourBlack, 0)
end
end
-- Handler for triggers from long-descriptions
function MapLongHandler (sName, sLine, wildcards)
--Note("Debug: Longfind, sName='" .. sName .. "', sThisRoomTitle='" .. sThisRoomTitle .. "'")
MinimapCheckSpecialID(sName, sThisRoomTitle)
RedrawMap()
end
-- Jump the visible map to a provided string text of co-ordinates in the format {mapid,xpos,ypos}
-- (provides no client output feedback, returns false if invalid data)
function MapJumptoCoordinates(sCoordinates)
local sValues = utils.split(sCoordinates, ',')
if (sValues[1] ~= nil) then
sValues[1] = tonumber(sValues[1])
if (sQuowMapfiles[sValues[1]] ~= nil) then
iCurMap = sValues[1]
sCurrentMap = sQuowMapfiles[iCurMap][1]
iMyX = tonumber(sValues[2]:match'^%s*(.*%S)')
iMyY = tonumber(sValues[3]:match'^%s*(.*%S)')
-- get a room ID if one matches this exact co-ordinate
sSQL = "SELECT room_id, map_id, xpos, ypos, room_short, room_type FROM rooms WHERE map_id=" .. iCurMap .. " AND xpos=" .. iMyX .. " AND ypos=" .. iMyY
for row in dbMap:nrows(sSQL) do
sClickedRoomID = row.room_id
break
end
RedrawMap()
Repaint()
return true
end
end
return false
end
-- Jump the visible map to a provided unique room ID
-- (provides no client output feedback, returns false if invalid data)
function QuowJumpToRoomID(sTargetRoomID)
if (sQuowLocationsByRoomID[sTargetRoomID] ~= nil) then
iCurMap = sQuowLocationsByRoomID[sTargetRoomID][1]
sCurrentMap = sQuowMapfiles[iCurMap][1]
iMyX = sQuowLocationsByRoomID[sTargetRoomID][2]
iMyY = sQuowLocationsByRoomID[sTargetRoomID][3]
sClickedRoomID = sTargetRoomID
RedrawMap()
Repaint()
return true
end
return false
end
-- Possible future external plugins ability to share/send group info?
function QuowGroupInfo()
return iTotalGroupMembers
end
-- For route testing A
function QuowTestRouteToRoomID(sTargetRoomID)
sDoPath, sFinalDestination, iResults = QuowRoutefind(sCurrentRoomID, sTargetRoomID, sQuowLocationsByRoomID[sTargetRoomID][1], sQuowLocationsByRoomID[sTargetRoomID][2], sQuowLocationsByRoomID[sTargetRoomID][3])
return sDoPath, sFinalDestination, iResults
end
-- For route testing B
function QuowTestDirectionToRoomID(sDirectionTest)
if (sQuowExitsByExit[sCurrentRoomID] ~= nil and sQuowExitsByExit[sCurrentRoomID][sDirectionTest] ~= nil) then
return sQuowExitsByExit[sCurrentRoomID][sDirectionTest]
else
return ""
end
end
-- Testing current room ID
function QuowTestCurrentRoomID()
return sCurrentRoomID
end
-- For route testing C
function QuowTestClosestPoint(sRoomList)
local sPossibles = utils.split(sRoomList, ',')
local iClosest = -1
local sClosest = ""
local sClosestPath = ""
local sValues, sTestX, sTestY, sTestZ
for iKey, sValue in pairs(sPossibles) do
local sTestDoPath, sTestFinalDestination, iTestResults = QuowRoutefind(sCurrentRoomID, sValue, sQuowLocationsByRoomID[sValue][1], sQuowLocationsByRoomID[sValue][2], sQuowLocationsByRoomID[sValue][3])
if (iClosest == -1 or iTestResults < iClosest) then
iClosest = iTestResults
sClosest = sValue
sClosestPath = sTestDoPath
end
end
return sClosestPath, sClosest, iClosest
end
-- For testing co-ordinates
function QuowTestGetRoomID(sCoordinates)
local sTestID = ""
local sValues = utils.split(string.sub(sCoordinates, 2, string.find(sCoordinates, "}") - 1), ',')
local sTestX = tonumber(sValues[2]:match'^%s*(.*%S)')
local sTestY = tonumber(sValues[3]:match'^%s*(.*%S)')
local sTestZ = tonumber(sValues[1]:match'^%s*(.*%S)')
sSQL = "SELECT room_id, map_id, xpos, ypos, room_short, room_type FROM rooms WHERE map_id=" .. sTestZ .. " AND xpos=" .. sTestX .. " AND ypos=" .. sTestY
for row in dbMap:nrows(sSQL) do
sTestID = row.room_id
break
end
if (sTestID ~= "" and sQuowLocationsByRoomID[sTestID] ~= nil) then
return sTestID
else
return ""
end
end
-- Attempt to provide a speedwalk to the given room ID from whatever our currently-thought room ID to be
function QuowRouteToRoomID(sTargetRoomID, bInstantSend)
-- Check for valid ID's before we do anything
if (bInstantSend == nil) then
bInstantSend = false
end
--Note("Target Room ID=" .. sTargetRoomID .. ", from room ID=" .. sCurrentRoomID .. ", Instantsend=" .. tostring(bInstantSend))
if (sTargetRoomID ~= nil and sCurrentRoomID ~= nil and sQuowLocationsByRoomID[sTargetRoomID] ~= nil and sQuowLocationsByRoomID[sCurrentRoomID] ~= nil) then
local sDoPath = ""
local iResults = 0
sDoPath, sFinalDestination, iResults = QuowRoutefind(sCurrentRoomID, sTargetRoomID, sQuowLocationsByRoomID[sTargetRoomID][1], sQuowLocationsByRoomID[sTargetRoomID][2], sQuowLocationsByRoomID[sTargetRoomID][3])
if (sDoPath ~= "") then
sDoPath = "alias MooMooQuowsRun " .. sDoPath
if (string.len(sDoPath) > 1700) then
Note(sDoPath)
else
SendNoEcho(sDoPath)
end
Tell("Found a path TO '")
ColourTell(sGlobalColourCyan, sGlobalColourBlack, sQuowLocationsByRoomID[sFinalDestination][4])
if (sQuowUserBookmarks[sFinalDestination] ~= nil and sQuowUserBookmarks[sFinalDestination] ~= "") then
ColourTell(sGlobalColourCyan, sGlobalColourBlack, " (" .. sQuowUserBookmarks[sFinalDestination] .. ")")
end
Tell("', FROM '")
ColourTell(sGlobalColourCyan, sGlobalColourBlack, sQuowLocationsByRoomID[sCurrentRoomID][4])
Note("'.")
Tell("Route requires ")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, iResults .. " moves")
if (string.len(sDoPath) > 1700) then
Note(".")
ColourNote("red", sGlobalColourBlack, "Warning: Speedwalk alias is too long to send to the mud, try and split your journey into two parts instead!")
else
if (bInstantSend == false) then
Tell(". Type/Click on '")
Hyperlink ("MooMooQuowsRun", "MooMooQuowsRun", "Run this speedwalk", sGlobalColourOrange, sGlobalColourBlack, 0)
Note("' to run the speedwalk!")
else
Note(". Starting speedwalk now!")
SendNoEcho("MooMooQuowsRun")
end
if (iResults > 140) then
Note("Warning: Your speedwalk route is very long, if your character is idle for more than 5 minutes while it runs, Discworld will clear your queue and stop the journey short.")
Note("(don't worry if this happens; you can generate a new speedwalk to your destination from wherever your character ends up)")
end
end
return true
else
Note("Sorry, was unable to generate a path, you'll have to use your legs!")
return false
end
else
Note("Sorry, unable to generate a path. You must be in a room recognised by the minimap, and have selected a recognised room first.")
return false
end
return false
end
-- **********************************************
-- ***** Automate Full Window Layout Themes *****
-- **********************************************
function QuowLayoutTheme(iLayoutWanted)
-- Pre-configured layout themes
local iTop = 0
local iLeft = 0
local iRight = GetInfo(281) - 1
local iBottom = GetInfo(280) - 1
if (iLayoutWanted == "RedrawTimer") then
iLayoutWanted = iThemeLayoutLocked
end
if (iLayoutWanted == 1) then
-- ****************************************
-- ***** Layout: Cow-Bar Classic Top *****
-- ****************************************
SCREENMARGINS = {
["left"] = {false, 10},
["top"] = {true, 234},
["right"] = {false, 10},
["bottom"] = {false, 10},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 280, ["HEIGHT"] = 280, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 180, ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 200, ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 3)) / 3), ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = (iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"] + WINDATA[winStats]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 3)), ["HEIGHT"] = 40, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMDT] = {["WIDTH"] = WINDATA[winBars]["WIDTH"], ["HEIGHT"] = 75, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 120, ["HEIGHT"] = 120, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = (iRight - (WINDATA[winAscii]["WIDTH"] + WINDATA[winMinimap]["WIDTH"])) + 2, ["HEIGHT"] = 120, ["SHOW"] = true, ["LOCKED"] = false}
-- Minimap
WindowPosition(winMinimap, iRight - WINDATA[winMinimap]["WIDTH"], 0, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Vitals bar
WindowPosition(winBars, 0, 0, 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- MDT
WindowPosition(winMDT, 0, 39, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Shields
WindowPosition(winShields, WINDATA[winBars]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- XP Graphs
WindowPosition(winXP, WINDATA[winBars]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 2, 0, 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Stats
WindowPosition(winStats, WINDATA[winBars]["WIDTH"] + WINDATA[winXP]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 3, 0, 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Comms
WindowPosition(winComms, 0, 113, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Ascii
WindowPosition(winAscii, iRight - WINDATA[winMinimap]["WIDTH"] - WINDATA[winAscii]["WIDTH"], 113, 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Healthbar stacking
bVitalStacking = false
elseif (iLayoutWanted == 2) then
-- *****************************************
-- ***** Layout: Cow-Bar Classic Left *****
-- *****************************************
SCREENMARGINS = {
["left"] = {true, 192},
["top"] = {false, 160},
["right"] = {false, 10},
["bottom"] = {false, 10},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 300, ["HEIGHT"] = 300, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = 190, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 190, ["HEIGHT"] = 160, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 190, ["HEIGHT"] = 130, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 190, ["HEIGHT"] = 130, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = 190, ["HEIGHT"] = iBottom - (WINDATA[winAscii]["HEIGHT"] + WINDATA[winXP]["HEIGHT"] + WINDATA[winBars]["HEIGHT"] + WINDATA[winShields]["HEIGHT"]) + 4, ["SHOW"] = true, ["LOCKED"] = false}
if (iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) >= 900) then
WINDATA[winMDT] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) + 2) * 0.30), ["HEIGHT"] = 160, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) + 2) * 0.70), ["HEIGHT"] = 160, ["SHOW"] = true, ["LOCKED"] = false}
else
WINDATA[winMDT] = {["WIDTH"] = iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]), ["HEIGHT"] = 70, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]), ["HEIGHT"] = 140, ["SHOW"] = true, ["LOCKED"] = false}
end
-- Minimap
WindowPosition(winMinimap, iRight - WINDATA[winMinimap]["WIDTH"], 0, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- XP Graphs
WindowPosition(winXP, 0, 0, 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Vitals bar
WindowPosition(winBars, 0, iBottom - WINDATA[winBars]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- Shields
WindowPosition(winShields, 0, iTop + WINDATA[winXP]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- Stats
WindowPosition(winStats, 0, iTop + WINDATA[winXP]["HEIGHT"] + WINDATA[winShields]["HEIGHT"] - 2, 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Ascii
WindowPosition(winAscii, 0, iBottom - (WINDATA[winBars]["HEIGHT"] + WINDATA[winAscii]["HEIGHT"] - 1), 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Vertical or horizontal chat + MDT?
if (iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) >= 900) then
-- Comms
WindowPosition(winComms, WINDATA[winXP]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- MDT
WindowPosition(winMDT, WINDATA[winXP]["WIDTH"] + WINDATA[winComms]["WIDTH"] - 2, 0, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
else
-- Comms
WindowPosition(winComms, WINDATA[winXP]["WIDTH"] - 1, WINDATA[winMDT]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- MDT
WindowPosition(winMDT, WINDATA[winXP]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
end
-- Healthbar stacking
bVitalStacking = true
elseif (iLayoutWanted == 3) then
-- ******************************************
-- ***** Layout: Cow-Bar Classic Right *****
-- ******************************************
SCREENMARGINS = {
["left"] = {false, 10},
["top"] = {false, 160},
["right"] = {true, 192},
["bottom"] = {false, 10},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 300, ["HEIGHT"] = 300, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = 190, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 190, ["HEIGHT"] = 160, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 190, ["HEIGHT"] = 130, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 190, ["HEIGHT"] = 130, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = 190, ["HEIGHT"] = iBottom - (WINDATA[winAscii]["HEIGHT"] + WINDATA[winXP]["HEIGHT"] + WINDATA[winBars]["HEIGHT"] + WINDATA[winShields]["HEIGHT"]) + 4, ["SHOW"] = true, ["LOCKED"] = false}
if (iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) >= 900) then
WINDATA[winMDT] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) + 2) * 0.30), ["HEIGHT"] = 160, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) + 2) * 0.70), ["HEIGHT"] = 160, ["SHOW"] = true, ["LOCKED"] = false}
else
WINDATA[winMDT] = {["WIDTH"] = iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]), ["HEIGHT"] = 70, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]), ["HEIGHT"] = 140, ["SHOW"] = true, ["LOCKED"] = false}
end
-- XP Graphs
WindowPosition(winXP, iRight - WINDATA[winXP]["WIDTH"], 0, 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Vitals bar
WindowPosition(winBars, iRight - WINDATA[winXP]["WIDTH"], iBottom - WINDATA[winBars]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- Shields
WindowPosition(winShields, iRight - (WINDATA[winBars]["WIDTH"]), iTop + WINDATA[winXP]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- Stats
WindowPosition(winStats, iRight - WINDATA[winStats]["WIDTH"], iTop + WINDATA[winXP]["HEIGHT"] + WINDATA[winShields]["HEIGHT"] - 2, 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Minimap
WindowPosition(winMinimap, iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]), 0, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Ascii
WindowPosition(winAscii, iRight - WINDATA[winAscii]["WIDTH"], iBottom - (WINDATA[winBars]["HEIGHT"] + WINDATA[winAscii]["HEIGHT"] - 1), 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Vertical or horizontal chat + MDT?
if (iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) >= 900) then
-- Comms
WindowPosition(winComms, 0, 0, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- MDT
WindowPosition(winMDT, WINDATA[winComms]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
else
-- Comms
WindowPosition(winComms, WINDATA[winXP]["WIDTH"] - 1, WINDATA[winMDT]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- MDT
WindowPosition(winMDT, WINDATA[winXP]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
end
-- Healthbar stacking
bVitalStacking = true
elseif (iLayoutWanted == 4) then
-- *******************************************
-- ***** Layout: Cow-Bar Classic Bottom *****
-- *******************************************
SCREENMARGINS = {
["left"] = {false, 10},
["top"] = {false, 10},
["right"] = {false, 10},
["bottom"] = {true, 230},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 300, ["HEIGHT"] = 300, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 180, ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 200, ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 3)) / 3), ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = (iRight - (WINDATA[winXP]["WIDTH"] + WINDATA[winMinimap]["WIDTH"] + WINDATA[winStats]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 3)), ["HEIGHT"] = 40, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMDT] = {["WIDTH"] = WINDATA[winBars]["WIDTH"], ["HEIGHT"] = 75, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 120, ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = (iRight - (WINDATA[winAscii]["WIDTH"] + WINDATA[winMinimap]["WIDTH"])) + 2, ["HEIGHT"] = 114, ["SHOW"] = true, ["LOCKED"] = false}
-- Minimap
WindowPosition(winMinimap, iRight - WINDATA[winMinimap]["WIDTH"], iBottom - WINDATA[winMinimap]["HEIGHT"], 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Vitals bar
WindowPosition(winBars, 0, iBottom - WINDATA[winBars]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- MDT
WindowPosition(winMDT, 0, iBottom - (WINDATA[winMDT]["HEIGHT"] + WINDATA[winBars]["HEIGHT"]) + 1, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Shields
WindowPosition(winShields, WINDATA[winBars]["WIDTH"] - 1, iBottom - WINDATA[winXP]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- XP Graphs
WindowPosition(winXP, WINDATA[winBars]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 2, iBottom - WINDATA[winXP]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Stats
WindowPosition(winStats, WINDATA[winBars]["WIDTH"] + WINDATA[winXP]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 3, iBottom - WINDATA[winStats]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Comms
WindowPosition(winComms, 0, iBottom - 227, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Ascii
WindowPosition(winAscii, iRight - WINDATA[winMinimap]["WIDTH"] - WINDATA[winAscii]["WIDTH"], iBottom - 227, 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Healthbar stacking
bVitalStacking = false
elseif (iLayoutWanted == 11) then
-- *******************************
-- ***** Layout: Simple Cow *****
-- *******************************
local iSpecialWidth = iRight * 0.16
if (iSpecialWidth < 220) then
iSpecialWidth = 220
elseif (iSpecialWidth > 260) then
iSpecialWidth = 260
end
SCREENMARGINS = {
["left"] = {true, iSpecialWidth + 2},
["top"] = {false, 160},
["right"] = {false, 10},
["bottom"] = {false, 10},
}
-- Re-do window sizes
WINDATA[winBars] = {["WIDTH"] = iSpecialWidth, ["HEIGHT"] = 100, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = iSpecialWidth, ["HEIGHT"] = 54, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = iSpecialWidth, ["HEIGHT"] = 103, ["SHOW"] = false, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = iSpecialWidth, ["HEIGHT"] = 220, ["SHOW"] = false, ["LOCKED"] = false}
if ((iRight - WINDATA[winXP]["WIDTH"]) >= 900) then
WINDATA[winMDT] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"]) + 3) * 0.25), ["HEIGHT"] = 150, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = math.floor((iRight - (WINDATA[winXP]["WIDTH"]) + 3) * 0.75), ["HEIGHT"] = 150, ["SHOW"] = true, ["LOCKED"] = false}
else
WINDATA[winMDT] = {["WIDTH"] = iRight - WINDATA[winXP]["WIDTH"], ["HEIGHT"] = 70, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - WINDATA[winXP]["WIDTH"], ["HEIGHT"] = 140, ["SHOW"] = true, ["LOCKED"] = false}
end
WINDATA[winAscii] = {["WIDTH"] = iSpecialWidth, ["HEIGHT"] = math.floor((iBottom - (WINDATA[winBars]["HEIGHT"] + WINDATA[winXP]["HEIGHT"]) + 2) * 0.3), ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMinimap] = {["WIDTH"] = iSpecialWidth, ["HEIGHT"] = math.floor((iBottom - (WINDATA[winBars]["HEIGHT"] + WINDATA[winXP]["HEIGHT"]) + 2) * 0.7), ["SHOW"] = true, ["LOCKED"] = false}
-- Stats
WindowPosition(winStats, iRight - WINDATA[winStats]["WIDTH"] - 1, iBottom - WINDATA[winStats]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Shields
WindowPosition(winShields, iRight - WINDATA[winStats]["WIDTH"] - 1, iBottom - (WINDATA[winShields]["HEIGHT"] + WINDATA[winStats]["HEIGHT"] + 1), 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- Vitals bar
WindowPosition(winBars, 0, iBottom - WINDATA[winBars]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- XP Graphs
WindowPosition(winXP, 0, iBottom - (WINDATA[winXP]["HEIGHT"] + WINDATA[winBars]["HEIGHT"] - 1), 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Ascii
WindowPosition(winAscii, 0, iBottom - (WINDATA[winXP]["HEIGHT"] + WINDATA[winAscii]["HEIGHT"] + WINDATA[winBars]["HEIGHT"] - 2), 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Minimap
WindowPosition(winMinimap, 0, 0, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Vertical or horizontal chat + MDT?
if ((iRight - WINDATA[winXP]["WIDTH"]) >= 900) then
-- Comms
WindowPosition(winComms, WINDATA[winXP]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- MDT
WindowPosition(winMDT, WINDATA[winXP]["WIDTH"] + WINDATA[winComms]["WIDTH"] - 2, 0, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
else
-- Comms
WindowPosition(winComms, WINDATA[winXP]["WIDTH"] - 1, WINDATA[winMDT]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- MDT
WindowPosition(winMDT, WINDATA[winXP]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
end
-- Healthbar stacking
bVitalStacking = true
elseif (iLayoutWanted == 5) then
-- *****************************************
-- ***** Layout: Micro-Cow Miniatures *****
-- *****************************************
SCREENMARGINS = {
["left"] = {true, 172},
["top"] = {false, 80},
["right"] = {false, 10},
["bottom"] = {false, 10},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 170, ["HEIGHT"] = 210, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = 170, ["HEIGHT"] = 60, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 170, ["HEIGHT"] = 48, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 170, ["HEIGHT"] = 48, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 170, ["HEIGHT"] = 80, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMDT] = {["WIDTH"] = 170, ["HEIGHT"] = math.floor((iBottom - (WINDATA[winMinimap]["HEIGHT"] + WINDATA[winBars]["HEIGHT"] + WINDATA[winXP]["HEIGHT"] + WINDATA[winShields]["HEIGHT"] + WINDATA[winAscii]["HEIGHT"] - 5)) / 2), ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = 170, ["HEIGHT"] = math.floor((iBottom - (WINDATA[winMinimap]["HEIGHT"] + WINDATA[winBars]["HEIGHT"] + WINDATA[winXP]["HEIGHT"] + WINDATA[winShields]["HEIGHT"] + WINDATA[winAscii]["HEIGHT"] - 5)) / 2), ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - WINDATA[winBars]["WIDTH"] + 1, ["HEIGHT"] = 80, ["SHOW"] = true, ["LOCKED"] = false}
-- Ascii
WindowPosition(winAscii, 0, iBottom - WINDATA[winAscii]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- MDT
WindowPosition(winMDT, 0, iBottom - (WINDATA[winMDT]["HEIGHT"] + WINDATA[winAscii]["HEIGHT"]) + 2, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Minimap
WindowPosition(winMinimap, 0, iBottom - (WINDATA[winMinimap]["HEIGHT"] + WINDATA[winMDT]["HEIGHT"] + WINDATA[winAscii]["HEIGHT"]) + 3, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Vitals bar
WindowPosition(winBars, 0, 0, 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- XP Graphs
WindowPosition(winXP, 0, WINDATA[winBars]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Shields
WindowPosition(winShields, 0, (WINDATA[winBars]["HEIGHT"] + WINDATA[winXP]["HEIGHT"]) - 2, 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- Stats
WindowPosition(winStats, 0, (WINDATA[winBars]["HEIGHT"] + WINDATA[winXP]["HEIGHT"] + WINDATA[winShields]["HEIGHT"]) - 3, 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Comms
WindowPosition(winComms, WINDATA[winBars]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Healthbar stacking
bVitalStacking = true
elseif (iLayoutWanted == 6) then
-- *****************************************
-- ***** Layout: Big-Cows Big-Windows *****
-- *****************************************
SCREENMARGINS = {
["left"] = {true, 307},
["top"] = {true, 200},
["right"] = {true, 400},
["bottom"] = {false, 10},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 400, ["HEIGHT"] = 400, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMDT] = {["WIDTH"] = 400, ["HEIGHT"] = iBottom - WINDATA[winMinimap]["HEIGHT"], ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = 305, ["HEIGHT"] = 120, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 305, ["HEIGHT"] = 200, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 180, ["HEIGHT"] = 190, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 126, ["HEIGHT"] = 190, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - (WINDATA[winBars]["WIDTH"] + WINDATA[winMinimap]["WIDTH"]) + 2, ["HEIGHT"] = 200, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = 305, ["HEIGHT"] = iBottom - (WINDATA[winXP]["HEIGHT"] + WINDATA[winBars]["HEIGHT"] + WINDATA[winShields]["HEIGHT"]), ["SHOW"] = true, ["LOCKED"] = false}
-- Minimap
WindowPosition(winMinimap, iRight - WINDATA[winMinimap]["WIDTH"], 0, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- XP Graphs
WindowPosition(winXP, 0, 0, 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Stats
WindowPosition(winStats, 0, WINDATA[winXP]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Shields
WindowPosition(winShields, 0, WINDATA[winXP]["HEIGHT"] + WINDATA[winStats]["HEIGHT"] - 2, 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- Ascii
WindowPosition(winAscii, WINDATA[winShields]["WIDTH"] - 1, WINDATA[winXP]["HEIGHT"] + WINDATA[winStats]["HEIGHT"] - 2, 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Vitals bar
WindowPosition(winBars, 0, iBottom - WINDATA[winBars]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- MDT
WindowPosition(winMDT, iRight - WINDATA[winMDT]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Comms
WindowPosition(winComms, WINDATA[winXP]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Healthbar stacking
bVitalStacking = true
elseif (iLayoutWanted == 7) then
-- **************************************
-- ***** Layout: Marginalised Cows *****
-- **************************************
SCREENMARGINS = {
["left"] = {true, 190},
["top"] = {true, 170},
["right"] = {true, 300},
["bottom"] = {true, 52},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 300, ["HEIGHT"] = 300, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = 190, ["HEIGHT"] = iBottom - 338, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = iRight - (WINDATA[winMinimap]["WIDTH"] + WINDATA[winStats]["WIDTH"]) + 2, ["HEIGHT"] = 50, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 240, ["HEIGHT"] = 170, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 190, ["HEIGHT"] = 170, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMDT] = {["WIDTH"] = 300, ["HEIGHT"] = iBottom - (WINDATA[winMinimap]["HEIGHT"]), ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - (WINDATA[winMinimap]["WIDTH"] + WINDATA[winShields]["WIDTH"] + WINDATA[winXP]["WIDTH"]) + 3, ["HEIGHT"] = 170, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 190, ["HEIGHT"] = 170, ["SHOW"] = true, ["LOCKED"] = false}
-- Minimap
WindowPosition(winMinimap, iRight - WINDATA[winMinimap]["WIDTH"], 0, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Shields
WindowPosition(winShields, WINDATA[winXP]["WIDTH"] + WINDATA[winComms]["WIDTH"] - 2, 0, 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- XP Graphs
WindowPosition(winXP, 0, 0, 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Vitals bar
WindowPosition(winBars, WINDATA[winStats]["WIDTH"] - 1, iBottom - WINDATA[winBars]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- MDT
WindowPosition(winMDT, iRight - WINDATA[winMDT]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Stats
WindowPosition(winStats, 0, WINDATA[winXP]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Comms
WindowPosition(winComms, WINDATA[winXP]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Ascii
WindowPosition(winAscii, 0, iBottom - WINDATA[winAscii]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Healthbar stacking
bVitalStacking = false
elseif (iLayoutWanted == 8) then
-- *************************************
-- ***** Layout: Semi-Skimmed Top *****
-- *************************************
SCREENMARGINS = {
["left"] = {false, 10},
["top"] = {true, 174},
["right"] = {false, 10},
["bottom"] = {false, 10},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 260, ["HEIGHT"] = 174, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 180, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 210, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = 150, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = 190, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 120, ["HEIGHT"] = 174, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMDT] = {["WIDTH"] = iRight - (WINDATA[winMinimap]["WIDTH"] + WINDATA[winXP]["WIDTH"] + WINDATA[winShields]["WIDTH"] + WINDATA[winStats]["WIDTH"] + WINDATA[winBars]["WIDTH"] + WINDATA[winAscii]["WIDTH"]) + 9, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - WINDATA[winMinimap]["WIDTH"] - WINDATA[winAscii]["WIDTH"] + 2, ["HEIGHT"] = 101, ["SHOW"] = true, ["LOCKED"] = false}
-- Minimap
WindowPosition(winMinimap, iRight - WINDATA[winMinimap]["WIDTH"], 0, 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Vitals bar
WindowPosition(winBars, 0, 0, 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- MDT
WindowPosition(winMDT, WINDATA[winBars]["WIDTH"] - 1, 0, 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Shields
WindowPosition(winShields, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] - 2, 0, 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- XP Graphs
WindowPosition(winXP, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 6, 0, 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Stats
WindowPosition(winStats, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] + WINDATA[winShields]["WIDTH"] + WINDATA[winXP]["WIDTH"] - 7, 0, 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Ascii
WindowPosition(winAscii, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] + WINDATA[winShields]["WIDTH"] + WINDATA[winXP]["WIDTH"] + WINDATA[winStats]["WIDTH"] - 8, 0, 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Comms
WindowPosition(winComms, 0, WINDATA[winBars]["HEIGHT"] - 1, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Healthbar stacking
bVitalStacking = true
elseif (iLayoutWanted == 9) then
-- ****************************************
-- ***** Layout: Semi-Skimmed Bottom *****
-- ****************************************
SCREENMARGINS = {
["left"] = {false, 10},
["top"] = {false, 10},
["right"] = {false, 10},
["bottom"] = {true, 174},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = 260, ["HEIGHT"] = 174, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winXP] = {["WIDTH"] = 180, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winShields] = {["WIDTH"] = 210, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winStats] = {["WIDTH"] = 150, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winBars] = {["WIDTH"] = 190, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winAscii] = {["WIDTH"] = 120, ["HEIGHT"] = 174, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winMDT] = {["WIDTH"] = iRight - (WINDATA[winMinimap]["WIDTH"] + WINDATA[winXP]["WIDTH"] + WINDATA[winShields]["WIDTH"] + WINDATA[winStats]["WIDTH"] + WINDATA[winBars]["WIDTH"] + WINDATA[winAscii]["WIDTH"]) + 9, ["HEIGHT"] = 74, ["SHOW"] = true, ["LOCKED"] = false}
WINDATA[winComms] = {["WIDTH"] = iRight - WINDATA[winMinimap]["WIDTH"] - WINDATA[winAscii]["WIDTH"] + 2, ["HEIGHT"] = 101, ["SHOW"] = true, ["LOCKED"] = false}
-- Minimap
WindowPosition(winMinimap, iRight - WINDATA[winMinimap]["WIDTH"], iBottom - WINDATA[winMinimap]["HEIGHT"], 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Vitals bar
WindowPosition(winBars, 0, iBottom - WINDATA[winBars]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- MDT
WindowPosition(winMDT, WINDATA[winBars]["WIDTH"] - 1, iBottom - WINDATA[winMDT]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Shields
WindowPosition(winShields, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] - 2, iBottom - WINDATA[winShields]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- XP Graphs
WindowPosition(winXP, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] + WINDATA[winShields]["WIDTH"] - 6, iBottom - WINDATA[winXP]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Stats
WindowPosition(winStats, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] + WINDATA[winShields]["WIDTH"] + WINDATA[winXP]["WIDTH"] - 7, iBottom - WINDATA[winStats]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Ascii
WindowPosition(winAscii, WINDATA[winBars]["WIDTH"] + WINDATA[winMDT]["WIDTH"] + WINDATA[winShields]["WIDTH"] + WINDATA[winXP]["WIDTH"] + WINDATA[winStats]["WIDTH"] - 8, iBottom - WINDATA[winAscii]["HEIGHT"], 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Ascii")
-- Comms
WindowPosition(winComms, 0, iBottom - (WINDATA[winBars]["HEIGHT"] + WINDATA[winComms]["HEIGHT"]) + 1, 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Healthbar stacking
bVitalStacking = true
elseif (iLayoutWanted == 10) then
-- ********************************
-- ***** Layout: Custom Cows *****
-- ********************************
SCREENMARGINS = {
["left"] = {CUSTOMCOWS["MARGINS"]["left"][1], CUSTOMCOWS["MARGINS"]["left"][2]},
["top"] = {CUSTOMCOWS["MARGINS"]["top"][1], CUSTOMCOWS["MARGINS"]["top"][2]},
["right"] = {CUSTOMCOWS["MARGINS"]["right"][1], CUSTOMCOWS["MARGINS"]["right"][2]},
["bottom"] = {CUSTOMCOWS["MARGINS"]["bottom"][1], CUSTOMCOWS["MARGINS"]["bottom"][2]},
}
-- Re-do window sizes
WINDATA[winMinimap] = {["WIDTH"] = CUSTOMCOWS[winMinimap]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winMinimap]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winMinimap]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winMinimap]["LOCKED"]}
WINDATA[winBars] = {["WIDTH"] = CUSTOMCOWS[winBars]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winBars]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winBars]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winBars]["LOCKED"]}
WINDATA[winStats] = {["WIDTH"] = CUSTOMCOWS[winStats]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winStats]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winStats]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winStats]["LOCKED"]}
WINDATA[winXP] = {["WIDTH"] = CUSTOMCOWS[winXP]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winXP]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winXP]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winXP]["LOCKED"]}
WINDATA[winMDT] = {["WIDTH"] = CUSTOMCOWS[winMDT]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winMDT]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winMDT]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winMDT]["LOCKED"]}
WINDATA[winShields] = {["WIDTH"] = CUSTOMCOWS[winShields]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winShields]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winShields]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winShields]["LOCKED"]}
WINDATA[winComms] = {["WIDTH"] = CUSTOMCOWS[winComms]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winComms]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winComms]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winComms]["LOCKED"]}
WINDATA[winAscii] = {["WIDTH"] = CUSTOMCOWS[winAscii]["WIDTH"], ["HEIGHT"] = CUSTOMCOWS[winAscii]["HEIGHT"], ["SHOW"] = CUSTOMCOWS[winAscii]["SHOW"], ["LOCKED"] = CUSTOMCOWS[winAscii]["LOCKED"]}
-- Minimap
WindowPosition(winMinimap, CUSTOMCOWS[winMinimap]["X"], CUSTOMCOWS[winMinimap]["Y"], 0, 2)
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- XP Graphs
WindowPosition(winXP, CUSTOMCOWS[winXP]["X"], CUSTOMCOWS[winXP]["Y"], 0, 2)
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], "XP")
-- Vitals bar
WindowPosition(winBars, CUSTOMCOWS[winBars]["X"], CUSTOMCOWS[winBars]["Y"], 0, 2)
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], "Bar")
-- MDT
WindowPosition(winMDT, CUSTOMCOWS[winMDT]["X"], CUSTOMCOWS[winMDT]["Y"], 0, 2)
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], "MDT")
-- Stats
WindowPosition(winStats, CUSTOMCOWS[winStats]["X"], CUSTOMCOWS[winStats]["Y"], 0, 2)
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], "Stats")
-- Shields
WindowPosition(winShields, CUSTOMCOWS[winShields]["X"], CUSTOMCOWS[winShields]["Y"], 0, 2)
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], "Shields")
-- Comms
WindowPosition(winComms, CUSTOMCOWS[winComms]["X"], CUSTOMCOWS[winComms]["Y"], 0, 2)
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], "Comms")
-- Ascii
WindowPosition(winAscii, CUSTOMCOWS[winAscii]["X"], CUSTOMCOWS[winAscii]["Y"], 0, 2)
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], "Comms")
-- Healthbar stacking
bVitalStacking = CUSTOMCOWS["OPTIONS"]["STACK"]
end
-- Set this theme as "locked" until user makes changes, unless it's a custom one loading
iThemeLayoutLocked = iLayoutWanted
-- Re-do margins
RedoScreenMargins()
-- Move the secret margin windows
WindowPosition(winScreenMarginLeft, SCREENMARGINS["left"][2] - 4, 0, 0, 2)
WindowPosition(winScreenMarginTop, 0, SCREENMARGINS["top"][2] - 4, 0, 2)
WindowPosition(winScreenMarginRight, GetInfo(281) - SCREENMARGINS["right"][2], 0, 0, 2)
WindowPosition(winScreenMarginBottom, 0, GetInfo(280) - SCREENMARGINS["bottom"][2], 0, 2)
-- Update the movewindow data values
winInfoMinimap.window_left = WindowInfo(winMinimap, 10)
winInfoMinimap.window_top = WindowInfo(winMinimap, 11)
winInfoBars.window_left = WindowInfo(winBars, 10)
winInfoBars.window_top = WindowInfo(winBars, 11)
winInfoStats.window_left = WindowInfo(winStats, 10)
winInfoStats.window_top = WindowInfo(winStats, 11)
winInfoXP.window_left = WindowInfo(winXP, 10)
winInfoXP.window_top = WindowInfo(winXP, 11)
winInfoMDT.window_left = WindowInfo(winMDT, 10)
winInfoMDT.window_top = WindowInfo(winMDT, 11)
winInfoShields.window_left = WindowInfo(winShields, 10)
winInfoShields.window_top = WindowInfo(winShields, 11)
winInfoComms.window_left = WindowInfo(winComms, 10)
winInfoComms.window_top = WindowInfo(winComms, 11)
winInfoAscii.window_left = WindowInfo(winAscii, 10)
winInfoAscii.window_top = WindowInfo(winAscii, 11)
-- Now make sure all other miniwindow contents are redrawn
bMinimapHidden = false
bMinimapTempHidden = false
if (MODULES["vitals"] == true) then
RedrawVitalsWindow()
WindowShow(winBars, WINDATA[winBars]["SHOW"])
else
WINDATA[winBars]["SHOW"] = false
end
if (MODULES["mdt"] == true) then
RedrawMDTWindow()
WindowShow(winMDT, WINDATA[winMDT]["SHOW"])
else
WINDATA[winMDT]["SHOW"] = false
end
if (MODULES["xp"] == true) then
RedrawXPWindow(true)
WindowShow(winXP, WINDATA[winXP]["SHOW"])
else
WINDATA[winXP]["SHOW"] = false
end
if (MODULES["stats"] == true) then
RedrawStatsWindow()
WindowShow(winStats, WINDATA[winStats]["SHOW"])
else
WINDATA[winStats]["SHOW"] = false
end
if (MODULES["shields"] == true) then
RedrawShieldsWindow()
WindowShow(winShields, WINDATA[winShields]["SHOW"])
else
WINDATA[winXP]["winShields"] = false
end
if (MODULES["comms"] == true) then
bCommsNeedsButtons = true
RedrawCommsWindow()
WindowShow(winComms, WINDATA[winComms]["SHOW"])
else
WINDATA[winXP]["winComms"] = false
end
if (MODULES["ascii"] == true) then
RedrawAsciiWindow()
WindowShow(winAscii, WINDATA[winAscii]["SHOW"])
else
WINDATA[winXP]["winAscii"] = false
end
WindowShow(winMinimap, WINDATA[winMinimap]["SHOW"])
RedrawMap()
end
-- **************************************
-- ***** Custom Cow Layout Saving *****
-- **************************************
function QuowSaveCustomCows()
iThemeLayoutLocked = 10
CUSTOMCOWS = {
["MARGINS"] = {
["left"] = {SCREENMARGINS["left"][1], SCREENMARGINS["left"][2]},
["top"] = {SCREENMARGINS["top"][1], SCREENMARGINS["top"][2]},
["right"] = {SCREENMARGINS["right"][1], SCREENMARGINS["right"][2]},
["bottom"] = {SCREENMARGINS["bottom"][1], SCREENMARGINS["bottom"][2]},
},
[winMinimap] = { ["WIDTH"] = WINDATA[winMinimap]["WIDTH"], ["HEIGHT"] = WINDATA[winMinimap]["HEIGHT"], ["SHOW"] = WINDATA[winMinimap]["SHOW"], ["LOCKED"] = WINDATA[winMinimap]["LOCKED"], ["X"] = WindowInfo(winMinimap, 10), ["Y"] = WindowInfo(winMinimap, 11) },
[winMDT] = { ["WIDTH"] = WINDATA[winMDT]["WIDTH"], ["HEIGHT"] = WINDATA[winMDT]["HEIGHT"], ["SHOW"] = WINDATA[winMDT]["SHOW"], ["LOCKED"] = WINDATA[winMDT]["LOCKED"], ["X"] = WindowInfo(winMDT, 10), ["Y"] = WindowInfo(winMDT, 11) },
[winBars] = { ["WIDTH"] = WINDATA[winBars]["WIDTH"], ["HEIGHT"] = WINDATA[winBars]["HEIGHT"], ["SHOW"] = WINDATA[winBars]["SHOW"], ["LOCKED"] = WINDATA[winBars]["LOCKED"], ["X"] = WindowInfo(winBars, 10), ["Y"] = WindowInfo(winBars, 11) },
[winStats] = { ["WIDTH"] = WINDATA[winStats]["WIDTH"] , ["HEIGHT"] = WINDATA[winStats]["HEIGHT"], ["SHOW"] = WINDATA[winStats]["SHOW"], ["LOCKED"] = WINDATA[winStats]["LOCKED"], ["X"] = WindowInfo(winStats, 10), ["Y"] = WindowInfo(winStats, 11) },
[winXP] = { ["WIDTH"] = WINDATA[winXP]["WIDTH"], ["HEIGHT"] = WINDATA[winXP]["HEIGHT"], ["SHOW"] = WINDATA[winXP]["SHOW"], ["LOCKED"] = WINDATA[winXP]["LOCKED"], ["X"] = WindowInfo(winXP, 10), ["Y"] = WindowInfo(winXP, 11) },
[winShields] = { ["WIDTH"] = WINDATA[winShields]["WIDTH"], ["HEIGHT"] = WINDATA[winShields]["HEIGHT"], ["SHOW"] = WINDATA[winShields]["SHOW"], ["LOCKED"] = WINDATA[winShields]["LOCKED"], ["X"] = WindowInfo(winShields, 10), ["Y"] = WindowInfo(winShields, 11) },
[winComms] = { ["WIDTH"] = WINDATA[winComms]["WIDTH"], ["HEIGHT"] = WINDATA[winComms]["HEIGHT"], ["SHOW"] = WINDATA[winComms]["SHOW"], ["LOCKED"] = WINDATA[winComms]["LOCKED"], ["X"] = WindowInfo(winComms, 10), ["Y"] = WindowInfo(winComms, 11) },
[winAscii] = { ["WIDTH"] = WINDATA[winAscii]["WIDTH"], ["HEIGHT"] = WINDATA[winAscii]["HEIGHT"], ["SHOW"] = WINDATA[winAscii]["SHOW"], ["LOCKED"] = WINDATA[winAscii]["LOCKED"], ["X"] = WindowInfo(winAscii, 10), ["Y"] = WindowInfo(winAscii, 11) },
["OPTIONS"] = { ["STACK"] = bVitalStacking, },
}
end
-- **********************************************
-- ***** "minimap" command alias handling *****
-- **********************************************
sMinimapSearchResults = {}
-- Handle all the possible command arguments the user can send using the "minimap xyz" commands
function QuowMapCommand (sName, sLine, wildcards)
-- First split off any possible arguments
local sArgument = string.sub(sLine, 9)
if (sArgument == "") then
return
end
local sOriginalArgument = sArgument
sArgument = string.lower(sArgument)
-- Fake movement to shift the minimap around in a grid-pattern
if (sQuowTrackMoves[sArgument] ~= nil) then
bTempUnlocked = true
MinimapHandleMovement(string.lower(wildcards[1]), false)
Repaint()
-- Display client-side options and current settings
elseif (sArgument == "bookmarks") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar Location Bookmarks:")
local iAnyBookmarks = QuowBookmarkList("")
if (iAnyBookmarks == 0) then
Note("You have no bookmarked rooms. You can create these by left-clicking a room on the map, and then selecting Bookmark in the right-click menu.")
end
-- Bookmark room player is currently stood in
elseif (sArgument == "bookmark") then
if (sCurrentRoomID ~= "") then
QuowCreateBookmark(sCurrentRoomID)
end
-- Display help file
elseif (sArgument == "help") then
DisplayHelpFile()
-- Shift the minimap window to the top-left and force-show it
elseif (sArgument == "reset") then
QuowLayoutTheme(2)
bMinimapHidden = false
bMinimapTempHidden = false
bHideOnTerrain = true
bShowDiscDate = true
bAsciiMapOmitted = false
bAutoShowHideAscii = false
bDrawSkeletonMode = false
bPredictiveMoves = false
bDrawOrbs = true
bShowGhost = true
QuowClearQueues()
QuowOldSnap()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Resetting the minimap window and basic settings...")
-- Shift the minimap window to the top-left and force-show it
elseif (string.sub(sArgument, 1, 11) == "brightness ") then
sArgument = string.sub(sArgument, 12)
iMinimapBrightness = tonumber(sArgument)
if (iMinimapBrightness < 50) then
iMinimapBrightness = 50
end
if (iMinimapBrightness > 100) then
iMinimapBrightness = 100
end
RedrawMap()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Minimap window brightness now set to: " .. iMinimapBrightness .. "%")
-- Force a fake direction-face, useful for the UU library to let it know which way you are ACTUALLY facing if you get lost
elseif (string.sub(sArgument, 1, 7) == "setdir ") then
sArgument = string.sub(sArgument, 8)
sArgument = sArgument:match'^%s*(.*%S)' or ''
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Attempting to re-align your last known direction to: '" .. sArgument .. "'")
if (sMovementShort[sArgument] ~= nil) then
sLastDir = sMovementShort[sArgument]
end
-- Re-position the map by snapping it to one of the four corners
elseif (sArgument == "topright") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Snapping minimap window to the top-right")
WindowPosition(winMinimap, GetInfo(281) - (WINDATA[winMinimap]["WIDTH"] + 2), 1, 0, 2)
winInfoMinimap.window_left = WindowInfo(winMinimap, 10)
winInfoMinimap.window_top = WindowInfo(winMinimap, 11)
elseif (sArgument == "topleft") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Snapping minimap window to the top-left")
WindowPosition(winMinimap, GetInfo(272), 1, 0, 2)
winInfoMinimap.window_left = WindowInfo(winMinimap, 10)
winInfoMinimap.window_top = WindowInfo(winMinimap, 11)
elseif (sArgument == "bottomright") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Snapping minimap window to the bottom-right")
WindowPosition(winMinimap, GetInfo(281) - (WINDATA[winMinimap]["WIDTH"] + 2), GetInfo(280) - (WINDATA[winMinimap]["HEIGHT"] + 2), 0, 2)
winInfoMinimap.window_left = WindowInfo(winMinimap, 10)
winInfoMinimap.window_top = WindowInfo(winMinimap, 11)
elseif (sArgument == "bottomleft") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Snapping minimap window to the bottom-left")
WindowPosition(winMinimap, GetInfo(272), GetInfo(280) - (WINDATA[winMinimap]["HEIGHT"] + 2), 0, 2)
winInfoMinimap.window_left = WindowInfo(winMinimap, 10)
winInfoMinimap.window_top = WindowInfo(winMinimap, 11)
-- Resize the map window by the given values
elseif (string.sub(sArgument, 1, 7) == "resize ") then
sArgument = string.gsub(string.sub(sArgument, 8), ' ', '')
local sValues = utils.split(sArgument, ',')
if (sValues[1] ~= nil and sValues[2] ~= nil) then
local iTempX = tonumber(sValues[1])
local iTempY = tonumber(sValues[2])
if iTempX < 20 then
iTempX = 20
end
if iTempX > 800 then
iTempX = 800
end
if iTempY < 20 then
iTempY = 20
end
if iTempY > 800 then
iTempY = 800
end
ResizeRedrawWindowMinimap(iTempX, iTempY)
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Use 'minimap resize x,y' to resize your minimap, for example 'minimap resize 220,220'")
end
-- Clear the minimap AND any queued movements
elseif (sArgument == "clear") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Clearing minimap and any stored movement command queues")
QuowClearQueues()
sCurrentMap = ""
sLoadedMap = ""
ClearMinimapWindow()
-- Clear any waiting queued movements
elseif (sArgument == "queue") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Clearing any stored/waiting movement queues")
QuowClearQueues()
RedrawMap()
elseif (sArgument == "discworldconfig") then
Send("alias QuowBarOptions options mxp enabled=on;options mxp objectmenus=off;options mxp livingmenus=off;options output map frame=off;options output map glance=top;options output map glancecity=top;options output map look=top;options output map lookcity=top;options output map plain=off;options output map reversecolour=off;options output map written=off;options output combat=verbose;options output prompt=off;options output shortinlong=on;options output usercolour=on;options combat monitor state=on;term ansi;term network")
Send("QuowBarOptions")
ColourNote("red", "black", "NOTE: Quow's Cow Bar is now re-configuring some of your Discworld options to match those Quow uses himself. This includes no command prompt (the '> '), verbose combat, and other settings.")
ColourNote("darkorange", "black", "Browse 'options' and the sub-options such as 'options output', 'options mxp', 'options output map' etc. and tweak to suit yourself!")
elseif (sArgument == "quowconfig" or sArgument == "mushconfig") then
SetOption ("alt_arrow_recalls_partial", 0)
SetOption ("always_record_command_history", 0)
SetOption ("arrows_change_history", 1)
SetOption ("arrow_keys_wrap", 0)
SetOption ("arrow_recalls_partial", 0)
SetOption ("auto_pause", 1)
SetOption ("auto_resize_command_window", 0)
SetOption ("auto_resize_minimum_lines", 1)
SetOption ("auto_resize_maximum_lines", 20)
SetOption ("auto_wrap_window_width", 1)
SetOption ("detect_pueblo", 1)
SetOption ("do_not_add_macros_to_command_history", 0)
SetOption ("do_not_show_outstanding_lines", 0)
SetOption ("do_not_translate_iac_to_iac_iac", 0)
SetOption ("disable_compression", 0)
SetOption ("enable_aliases", 1)
SetOption ("enable_auto_say", 0)
SetOption ("enable_scripts", 1)
SetOption ("enable_spam_prevention", 0)
SetOption ("enable_speed_walk", 0)
SetOption ("enable_timers", 1)
SetOption ("enable_triggers", 1)
SetOption ("enable_trigger_sounds", 1)
SetOption ("ignore_mxp_colour_changes", 0)
SetOption ("mud_can_change_link_colour", 1)
SetOption ("mud_can_remove_underline", 0)
SetOption ("mud_can_change_options", 1)
SetOption ("mxp_debug_level", 0)
SetOption ("play_sounds_in_background", 1)
SetOption ("re_evaluate_auto_say", 0)
SetOption ("save_deleted_command", 1)
SetOption ("save_world_automatically", 1)
SetOption ("send_echo", 0)
SetOption ("send_keep_alives", 0)
SetOption ("send_mxp_afk_response", 1)
SetOption ("show_connect_disconnect", 1)
SetOption ("spam_line_count", 20)
SetOption ("speed_walk_delay", 0)
SetOption ("spell_check_on_send", 0)
SetOption ("start_paused", 0)
SetOption ("translate_backslash_sequences", 0)
SetOption ("treeview_triggers", 1)
SetOption ("treeview_aliases", 1)
SetOption ("treeview_timers", 1)
SetOption ("underline_hyperlinks", 1)
SetOption ("unpause_on_send", 1)
SetOption ("use_mxp", 0)
SetOption ("utf_8", 0)
SetOption ("wrap", 0)
SetOption ("wrap_input", 0)
SetOption ("wrap_column", 168)
ColourNote("red", "black", "NOTE: Quow's Cow Bar has re-configured some of your world options to match those Quow uses himself.")
-- Insta-route to a named bookmark or numbered result
elseif (string.sub(sArgument, 1, 6) == "route ") then
sArgument = string.sub(sArgument, 7)
local sMatchBookmark = string.lower(sArgument)
local sUseBookmarkID = ""
local sBookmarkCompare = ""
-- First of all see if this is a number
if (tonumber(sMatchBookmark) ~= nil and sMinimapSearchResults[tonumber(sMatchBookmark)] ~= nil) then
QuowRouteToRoomID(sMinimapSearchResults[tonumber(sMatchBookmark)], true)
else
-- Loop through all bookmarks, try for an exact match otherwise a partial match
for sBookmarkedRoomID, sBookmarkNote in pairs(sQuowUserBookmarks) do
sBookmarkCompare = string.lower(sBookmarkNote)
if (sMatchBookmark == sBookmarkCompare or (sUseBookmarkID == "" and string.find(sBookmarkCompare, sMatchBookmark, 1, true) ~= nil)) then
sUseBookmarkID = sBookmarkedRoomID
end
end
if (sUseBookmarkID ~= "") then
if (sQuowLocationsByRoomID[sUseBookmarkID] ~= nil) then
QuowRouteToRoomID(sUseBookmarkID, true)
else
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Unable to find a route to the selected bookmark. There may be an error with your bookmarks or a path may be impossible.")
end
else
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Unable to find a bookmark with the name '" .. sArgument .. "' to speedwalk to.")
end
end
elseif (sArgument == "route") then
iMyX = iOldMX
iMyY = iOldMY
iCurMap = iOldMap
sCurrentMap = sOldMap
RedrawMap()
Repaint()
if (sClickedRoomID ~= "") then
if (sQuowLocationsByRoomID[sClickedRoomID] ~= nil) then
QuowRouteToRoomID(sClickedRoomID, true)
else
Note("Unable to find a route - ensure you click on a recognised room on the map first.")
end
else
Note("Unable to find a route - ensure you click on a recognised room on the map first.")
end
-- Lock/Unlock the minimap so it stops following you around in un-recognised zones
elseif (sArgument == "lock") then
if (bMapLocked == true) then
bMapLocked = false
Note("Map movement unlocked - will attempt to guess-track regardless of location")
else
bMapLocked = true
Note("Map movement locked - will NOT try to track in unrecognised rooms")
end
-- Special Quow admin edit mode for creating database entries of rooms
elseif (sArgument == "hotzonerecord") then
bRecordingHotzones = true
QuowHotspotStart()
-- Special Quow admin edit mode for creating database entries of rooms
elseif (sArgument == "editmode") then
if (bCreatingRooms == true) then
bCreatingRooms = false
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Disabling admin-only editor mode")
EnableTrigger("ShopInventory", false)
EnableAlias("QuowShortMM", false)
else
bCreatingRooms = true
sCurrentRoomID = ""
sOldRoomID = ""
bLastRoomFailGMCP = true
SendNoEcho("g")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "ENABLING admin-only room and shop-inventory edit mode.")
ColourNote("red", sGlobalColourBlack, "WARNINGS: Do NOT queue movements, go slowly, and be aware you may corrupt your room database!")
EnableTrigger("ShopInventory", true)
EnableAlias("QuowShortMM", true)
end
-- Additional to above, used for recording how two rooms connect to eachother
elseif (sArgument == "routemode") then
if (bIgnoreExits == true and bCreatingRooms == true) then
bIgnoreExits = false
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "ENABLING admin-only, room-link and route-pathing creation mode.")
ColourNote("red", sGlobalColourBlack, "WARNINGS: Do NOT queue movements, wait for the MUD each move, and ensure you do not use aliases to move!")
else
bIgnoreExits = true
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Disabling admin-only route editor mode")
end
-- Hide the minimap window
elseif (sArgument == "hide") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Hiding the minimap window. Use '", sGlobalColourCyan, sGlobalColourBlack, "minimap show", sGlobalColourOrange, sGlobalColourBlack, "' to display again.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Note: MANY options and features of Cow Bar are controlled through the minimap window menu!")
WindowShow(winMinimap, false)
WINDATA[winMinimap]["SHOW"] = false
iThemeLayoutLocked = 0
bMinimapHidden = true
bMinimapTempHidden = false
-- Show the minimap window
elseif (sArgument == "show") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Showing the minimap window. Use '", sGlobalColourCyan, sGlobalColourBlack, "minimap hide", sGlobalColourOrange, sGlobalColourBlack, "' to hide again.")
WindowShow(winMinimap, true)
WINDATA[winMinimap]["SHOW"] = true
iThemeLayoutLocked = 0
bMinimapHidden = false
bMinimapTempHidden = false
-- Jump to an exact co-ordinate in curly bracers
elseif (string.sub(sArgument, 1, 1) == "{" and string.find(sArgument, "}")) then
-- Let a user send co-ordinates to the minimap command in curly brackets
sClickedRoomID = ""
MapJumptoCoordinates(string.sub(sArgument, 2, string.find(sArgument, "}") - 1))
-- get a room ID if one matches this exact co-ordinate
sSQL = "SELECT room_id, map_id, xpos, ypos, room_short, room_type FROM rooms WHERE map_id=" .. iCurMap .. " AND xpos=" .. iMyX .. " AND ypos=" .. iMyY
for row in dbMap:nrows(sSQL) do
sClickedRoomID = row.room_id
break
end
if (sClickedRoomID ~= "" and string.sub(sArgument, -6) == " route" and sQuowLocationsByRoomID[sClickedRoomID] ~= nil) then
QuowRouteToRoomID(sClickedRoomID, true)
end
-- Search shop-stock inventory lines
elseif (string.sub(sArgument, 1, 5) == "item ") then
-- Try find a shop-based item
sArgument = string.sub(sArgument, 6)
sArgument = sArgument:match'^%s*(.*%S)' or ''
local iAnyFinds = 0
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Searching minimap item database for '" .. sArgument .. "'")
if (string.len(sArgument) < 3) then
Note("(your search string is too short to search the shop database, try a longer search!)")
else
for sKey, sFindLoc in pairs(sQuowShopItems) do
for sStockCode, sStocklist in pairs(sQuowShopItems[sKey]) do
if (string.find(string.lower(sStocklist[1]), sArgument, 1, true) ~= nil) then
iAnyFinds = iAnyFinds + 1
if (iAnyFinds == 1) then
sMinimapSearchResults = {}
end
Tell(string.format("%2d", iAnyFinds))
sMinimapSearchResults[iAnyFinds] = sKey
Tell(" [")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowJumpToRoomID(" .. sKey .. ")", "Show", "Display this location (" .. sQuowLocationsByRoomID[sKey][1] .. "," .. sQuowLocationsByRoomID[sKey][2] .. "," .. sQuowLocationsByRoomID[sKey][3] .. ") on the minimap", sGlobalColourOrange, "", 0)
Tell(" | ")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowRouteToRoomID(" .. sKey .. ")", "Route", "Attempt to find a speedwalk to this location (" .. sQuowLocationsByRoomID[sKey][1] .. "," .. sQuowLocationsByRoomID[sKey][2] .. "," .. sQuowLocationsByRoomID[sKey][3] .. ")", sGlobalColourOrange, "", 0)
Tell("] ")
ColourTell(sGlobalColourCyan, sGlobalColourBlack, sStocklist[1])
Tell(" @ ")
ColourTell(sGlobalColourCyan, sGlobalColourBlack, sStocklist[2])
Tell(" in " .. sQuowMapfiles[sQuowLocationsByRoomID[sKey][1]][2] .. " : " .. sQuowLocationsByRoomID[sKey][4])
Note("")
end
end
end
end
if (iAnyFinds == 0) then
Tell("Unable to find any known ")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "items")
Note(" containing '" .. sArgument .. "', you can try Kefka's Item Database site with this link:")
Hyperlink ("http://dw.daftjunk.com/items/index.php?search=" .. string.gsub(sArgument, " ", "+"), "http://dw.daftjunk.com/items/index.php?search=" .. string.gsub(sArgument, " ", "+"), "Click to search Kefka's site", "cyan", "", true)
Note("")
end
-- Search location databases for string
else
-- Try searching the ID database and shotcut-name database
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Searching minimap location database for '" .. sOriginalArgument .. "'")
sArgument = sArgument:match'^%s*(.*%S)' or ''
local iAnyFinds = 0
if (string.len(sArgument) < 4) then
Note("(your search string is too short to search the full location database, try a longer search!)")
else
for sKey, sFindLoc in pairs(sQuowLocationsByRoomID) do
if (string.find(string.lower(sFindLoc[4]), sArgument, 1, true) ~= nil) then
iAnyFinds = iAnyFinds + 1
if (iAnyFinds == 1) then
sMinimapSearchResults = {}
end
Tell(string.format("%2d", iAnyFinds))
sMinimapSearchResults[iAnyFinds] = sKey
Tell(" [")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowJumpToRoomID(" .. sKey .. ")", "Show", "Display this location (" .. sFindLoc[1] .. "," .. sFindLoc[2] .. "," .. sFindLoc[3] .. ") on the minimap", sGlobalColourOrange, "", 0)
Tell(" | ")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowRouteToRoomID(" .. sKey .. ")", "Route", "Attempt to find a speedwalk to this location (" .. sFindLoc[1] .. "," .. sFindLoc[2] .. "," .. sFindLoc[3] .. ")", sGlobalColourOrange, "", 0)
Tell("] ")
Tell(sQuowMapfiles[sFindLoc[1]][2] .. " : " .. sFindLoc[4])
Note("")
end
end
-- Search user bookmarks too
iAnyFinds = iAnyFinds + QuowBookmarkList(string.lower(sArgument))
end
if (sQuowPlaceLookups[sArgument] ~= nil) then
Note("")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "A shortcut location was found, perhaps you were looking for:")
local iPossMap = sQuowPlaceLookups[sArgument][1]
local iPossX = 0
local iPossY = 0
iAnyFinds = iAnyFinds + 1
if (sQuowPlaceLookups[sArgument][3] ~= nil) then
iPossX = sQuowPlaceLookups[sArgument][3]
else
iPossX = sQuowMapfiles[iPossMap][5]
end
if (sQuowPlaceLookups[sArgument][4] ~= nil) then
iPossY = sQuowPlaceLookups[sArgument][4]
else
iPossY = sQuowMapfiles[iPossMap][6]
end
-- get a room ID if one matches this exact co-ordinate
sSQL = "SELECT room_id, map_id, xpos, ypos, room_short, room_type FROM rooms WHERE map_id=" .. iPossMap .. " AND xpos=" .. iPossX .. " AND ypos=" .. iPossY
local sTempRouteRoute = ""
for row in dbMap:nrows(sSQL) do
sTempRouteRoute = row.room_id
break
end
local sLocString = iPossMap .. "," .. iPossX .. "," .. iPossY
Tell("[")
Hyperlink ("!!bfe35205f026786ea1d56e3b:MapJumptoCoordinates(" .. sLocString .. ")", "Show", "Display this location (" .. sLocString .. ") on the minimap", sGlobalColourOrange, "", 0)
if (sTempRouteRoute ~= "") then
Tell(" | ")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowRouteToRoomID(" .. sTempRouteRoute .. ")", "Route", "Attempt to find a speedwalk to this location (" .. iPossMap .. "," .. iPossX .. "," .. iPossY .. ")", sGlobalColourOrange, "", 0)
end
Tell("] " .. sQuowPlaceLookups[sArgument][2] .. " - " .. sQuowMapfiles[iPossMap][2])
Note("")
end
if (iAnyFinds == 0) then
Tell("Unable to find any known ")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, "locations")
Note(" with a [short name] containing '" .. sArgument .. "'.")
end
end
end -- End of "minimap" command handling
-- If user types "minimap" alone with no arguments
function MinimapCommandHandler(sName, sLine, wildcards)
local iThisX = iMyX
local iThisY = iMyY
local sThisLine = 'minimap {' .. tostring(iCurMap) .. ', ' .. tostring(iThisX) .. ', ' .. tostring(iThisY) .. '}'
Note("Your current minimap-position can be snapped to by another minimap user typing: '" .. sThisLine .. "'")
if (bDebugMode == true) then
Note("Debug: Current Room ID = " .. sCurrentRoomID .. " Clicked Room ID = " .. sClickedRoomID)
end
-- Handy when editing the room database, auto-clipboard this command
if (bCreatingRooms == true) then
SetClipboard(sThisLine)
end
-- If in admin edit mode, re-position the database position of our current room ID
if (sCurrentRoomID ~= "" and bCreatingRooms == true) then
if (sQuowLocationsByRoomID[sCurrentRoomID] == nil) then
sQuowLocationsByRoomID[sCurrentRoomID] = {iCurMap, iThisX, iThisY, sThisRoomTitle, sThisRoomType, 0}
sSQL = "INSERT INTO rooms VALUES ('" .. sCurrentRoomID .. "', " .. iCurMap ..", " .. iThisX .. ", " .. iThisY .. ", '" .. EscapeSQL(sThisRealRoomTitle) .. "', '" .. EscapeSQL(sThisRoomType) .. "', 0)"
assert(dbMap:execute(sSQL))
ColourNote(sGlobalColourOrange, sGlobalColourBlack, sSQL)
else
sQuowLocationsByRoomID[sCurrentRoomID][1] = iCurMap
sQuowLocationsByRoomID[sCurrentRoomID][2] = iThisX
sQuowLocationsByRoomID[sCurrentRoomID][3] = iThisY
sQuowLocationsByRoomID[sCurrentRoomID][4] = sThisRoomTitle
sQuowLocationsByRoomID[sCurrentRoomID][5] = sThisRoomType
sSQL = "UPDATE rooms SET map_id=" .. iCurMap ..", xpos=" .. iThisX .. ", ypos=" .. iThisY .. " WHERE room_id='" .. sCurrentRoomID .. "'"
assert(dbMap:execute(sSQL))
ColourNote(sGlobalColourCyan, sGlobalColourBlack, sSQL)
end
end
end
-- Distortion seen, draw a square
function UULibraryDistortion (sName, sLine, wildcards)
local iDistortDir = 0
if (wildcards[1] == "up ahead of") then
if (sLastDir == "n" or sLastDir == "north") then
iDistortDir = 1
elseif (sLastDir == "e" or sLastDir == "east") then
iDistortDir = 2
elseif (sLastDir == "s" or sLastDir == "south") then
iDistortDir = 3
elseif (sLastDir == "w" or sLastDir == "west") then
iDistortDir = 4
end
elseif (wildcards[1] == "to the right of") then
if (sLastDir == "n" or sLastDir == "north") then
iDistortDir = 2
elseif (sLastDir == "e" or sLastDir == "east") then
iDistortDir = 3
elseif (sLastDir == "s" or sLastDir == "south") then
iDistortDir = 4
elseif (sLastDir == "w" or sLastDir == "west") then
iDistortDir = 1
end
elseif (wildcards[1] == "behind") then
if (sLastDir == "n" or sLastDir == "north") then
iDistortDir = 3
elseif (sLastDir == "e" or sLastDir == "east") then
iDistortDir = 4
elseif (sLastDir == "s" or sLastDir == "south") then
iDistortDir = 1
elseif (sLastDir == "w" or sLastDir == "west") then
iDistortDir = 2
end
elseif (wildcards[1] == "to the left of") then
if (sLastDir == "n" or sLastDir == "north") then
iDistortDir = 4
elseif (sLastDir == "e" or sLastDir == "east") then
iDistortDir = 1
elseif (sLastDir == "s" or sLastDir == "south") then
iDistortDir = 2
elseif (sLastDir == "w" or sLastDir == "west") then
iDistortDir = 3
end
end
if (iDistortDir == 1) then
WindowRectOp (winMinimap, 2, MINIMAP_CX-17, MINIMAP_CY-21, MINIMAP_CX+17, MINIMAP_CY-14, ColourNameToRGB("red"))
WindowRectOp (winMinimap, 2, MINIMAP_CX-15, MINIMAP_CY-20, MINIMAP_CX+15, MINIMAP_CY-15, ColourNameToRGB("purple"))
elseif (iDistortDir == 2) then
WindowRectOp (winMinimap, 2, MINIMAP_CX+14, MINIMAP_CY-17, MINIMAP_CX+21, MINIMAP_CY+17, ColourNameToRGB("red"))
WindowRectOp (winMinimap, 2, MINIMAP_CX+15, MINIMAP_CY-15, MINIMAP_CX+20, MINIMAP_CY+15, ColourNameToRGB("purple"))
elseif (iDistortDir == 3) then
WindowRectOp (winMinimap, 2, MINIMAP_CX-17, MINIMAP_CY+14, MINIMAP_CX+17, MINIMAP_CY+21, ColourNameToRGB("red"))
WindowRectOp (winMinimap, 2, MINIMAP_CX-15, MINIMAP_CY+15, MINIMAP_CX+15, MINIMAP_CY+20, ColourNameToRGB("purple"))
elseif (iDistortDir == 4) then
WindowRectOp (winMinimap, 2, MINIMAP_CX-21, MINIMAP_CY-17, MINIMAP_CX-14, MINIMAP_CY+17, ColourNameToRGB("red"))
WindowRectOp (winMinimap, 2, MINIMAP_CX-20, MINIMAP_CY-15, MINIMAP_CX-15, MINIMAP_CY+15, ColourNameToRGB("purple"))
end
Repaint()
end
-- Check this Room ID is in our room ID database
function RoomIDMapFind()
-- Pop the first element from our movement queue
local iShiftMove = table.remove (iMapShiftQueue, 1)
-- Count this as a valid move (though we may just have glanced/looked...)
iTimeSinceLastMove = os.time()
-- Store last probably valid direction
sOldDir = sLastDir
-- Store real room title before we start changing it for special handlers
sThisRealRoomTitle = sThisRoomTitle
-- Object for quick reference of data
local objHere = nil
-- Do we recognise this room in our database?
if (sQuowLocationsByRoomID[sCurrentRoomID] ~= nil) then
iShadesRoom = 0
if (sFutureRoomID == "" or #iMapShiftQueue == 0) then
sFutureRoomID = sCurrentRoomID
end
objHere = sQuowLocationsByRoomID[sCurrentRoomID]
--Note("Debug: Found a database entry from the new room ID! ")
-- Check this map ID exists
if (sQuowMapfiles[objHere[1]] ~= nil) then
sCurrentMap = sQuowMapfiles[objHere[1]][1]
iCurMap = objHere[1]
BroadcastPlugin(1, "minimap.mapid {" .. iCurMap .. "}")
iCharLocMap = iCurMap
iMyX = objHere[2]
iMyY = objHere[3]
iOldMX = iMyX
iOldMY = iMyY
sOldMap = sCurrentMap
iOldMap = iCurMap
iCatchupX = iMyX
iCatchupY = iMyY
end
-- Unhide the minimap if we're temporarily hidden
if (bMinimapHidden == true and bMinimapTempHidden == true) then
bMinimapHidden = false
bMinimapTempHidden = false
WindowShow(winMinimap, true)
WINDATA[winMinimap]["SHOW"] = true
end
-- Hide the ASCII map if needed
if (bAutoShowHideAscii == true and MODULES["ascii"] == true and WINDATA[winAscii]["SHOW"] == true) then
WindowShow(winAscii, false)
WINDATA[winAscii]["SHOW"] = false
end
else
if (iShiftMove ~= nil) then
iMyX = iMyX + iShiftMove[1]
iMyY = iMyY + iShiftMove[2]
iOldMX = iMyX
iOldMY = iMyY
end
-- See if this is a "special id" instead
MinimapCheckSpecialID(sCurrentRoomID, sThisRoomTitle)
end
-- Edit-mode to create database entries
if (bCreatingRooms == true) then
if (sCurrentRoomID ~= sOldRoomID) then
if (sQuowLocationsByRoomID[sCurrentRoomID] == nil) then
local iThisX = iMyX
local iThisY = iMyY
sQuowLocationsByRoomID[sCurrentRoomID] = {iCurMap, iThisX, iThisY, sName, sThisRoomType, 0}
sSQL = "INSERT INTO rooms VALUES ('" .. sCurrentRoomID .. "', " .. iCurMap ..", " .. iThisX .. ", " .. iThisY .. ", '" .. EscapeSQL(sThisRealRoomTitle) .. "', '" .. EscapeSQL(sThisRoomType) .. "', 0)"
assert(dbMap:execute(sSQL))
ColourNote(sGlobalColourOrange, sGlobalColourBlack, sSQL)
if (sQuowExitsByID[sCurrentRoomID] == nil) then
sQuowExitsByID[sCurrentRoomID] = {}
end
if (sQuowExitsByExit[sCurrentRoomID] == nil) then
sQuowExitsByExit[sCurrentRoomID] = {}
end
end
if (sOldRoomID ~= "" and bLastRoomFailGMCP == false and bIgnoreExits == false) then
local sThisDir = DirectionConvert(sLastSentCommand)
if (sThisDir ~= nil and sThisDir ~= "") then
ColourNote(sGlobalColourCyan, sGlobalColourBlack, " [room_exits='" .. sOldRoomID .. "'='" .. sCurrentRoomID .. "' using '" .. sThisDir .. "']")
sSQL = "INSERT INTO room_exits VALUES ('" .. sOldRoomID .. "', '" .. sCurrentRoomID .."', '" .. sThisDir .. "', 0)"
assert(dbMap:execute(sSQL))
-- Double update to overwrite possible guess-returns
sSQL = "UPDATE room_exits SET exit='" .. sThisDir .. "', guessed=0 WHERE room_id='" .. sOldRoomID .. "' AND connect_id='" .. sCurrentRoomID .."'"
assert(dbMap:execute(sSQL))
if (sQuowExitsByID[sOldRoomID] == nil) then
sQuowExitsByID[sOldRoomID] = {}
end
sQuowExitsByID[sOldRoomID][sCurrentRoomID] = sThisDir
if (sQuowExitsByExit[sOldRoomID] == nil) then
sQuowExitsByExit[sOldRoomID] = {}
end
sQuowExitsByExit[sOldRoomID][sThisDir] = sCurrentRoomID
-- Guess reverse moves, only inserted so never overwriting
if (sReverseMove[sThisDir] ~= nil) then
sSQL = "INSERT INTO room_exits VALUES ('" .. sCurrentRoomID .. "', '" .. sOldRoomID .."', '" .. sReverseMove[sThisDir] .. "', 1)"
assert(dbMap:execute(sSQL))
if (sQuowExitsByID[sCurrentRoomID] == nil) then
sQuowExitsByID[sCurrentRoomID] = {}
end
if (sQuowExitsByID[sCurrentRoomID][sOldRoomID] == nil) then
sQuowExitsByID[sCurrentRoomID][sOldRoomID] = sReverseMove[sThisDir]
if (sQuowExitsByExit[sCurrentRoomID] == nil) then
sQuowExitsByExit[sCurrentRoomID] = {}
end
sQuowExitsByExit[sCurrentRoomID][sReverseMove[sThisDir]] = sOldRoomID
end
end
end
end
bLastRoomFailGMCP = false
else
--bLastRoomFailGMCP = true
Note(" [debug: this room has no GMCP data or we haven't moved]")
end
end
sOldRoomID = sCurrentRoomID
-- Finally redraw the graphical map
RedrawMap()
end
function MinimapCheckSpecialID(sApparentRoomID, sApparentRoomTitle)
-- Since this is not a recognised unique room ID, it might be an unwanted room - eg terrains - hide the minimap for these
if (sQuowTerrainRooms[sApparentRoomTitle] ~= nil) then
-- IN a terrain
-- Auto show-hide ASCII map?
if (bAutoShowHideAscii == true and MODULES["ascii"] == true and WINDATA[winAscii]["SHOW"] == false) then
WindowShow(winAscii, true)
WINDATA[winAscii]["SHOW"] = true
end
-- Auto-hide the main minimap in terrains
if (bHideOnTerrain == true and bMinimapHidden == false) then
bMinimapHidden = true
bMinimapTempHidden = true
WindowShow(winMinimap, false)
end
else
-- NOT in a terrain
-- Auto show-hide ASCII map?
if (bAutoShowHideAscii == true and MODULES["ascii"] == true and WINDATA[winAscii]["SHOW"] == true) then
WindowShow(winAscii, false)
WINDATA[winAscii]["SHOW"] = false
end
-- Auto-hide the main minimap in terrains
if (bHideOnTerrain == true and bMinimapHidden == true and bMinimapTempHidden == true) then
bMinimapHidden = false
bMinimapTempHidden = false
WindowShow(winMinimap, true)
end
end
-- Special Shades handler
iShadesRoom = 0
if (sCurrentRoomID == "01bbd8b887e71314d8e358cbaf4f585391206bc4" or sCurrentRoomID == "AMShades") then
-- Prepare by letting handlers know we need to locate the exact shades room
iShadesRoom = 18
-- Are we already on our way to a specific destination shades room? Set ourselves there now
if (iDestinationShadesRoom > 0) then
iShadesRoom = iDestinationShadesRoom
iDestinationShadesRoom = 0
end
iCatchupX = iMyX
iCatchupY = iMyY
iOldMX = iMyX
iOldMY = iMyY
sOldMap = sCurrentMap
iOldMap = iCurMap
-- Library handler
elseif (sApparentRoomID == "UULibrary") then
iCatchupX = iMyX
iCatchupY = iMyY
iOldMX = iMyX
iOldMY = iMyY
sOldMap = sCurrentMap
iOldMap = iCurMap
end
-- L-Space detector from room-title
if (iCurMap == 47 and (sApparentRoomID == "LSpace" or sApparentRoomID == "UnknownRoom")) then
bLSpaceDepths = true
ColourNote("red", sGlobalColourBlack, "Quow's Cow Bar Notice: Uh-oh, you have drifted into L-Space!")
Note("Library compass-directions won't work, library map has been cleared.")
Note("'refer liza' for useful guidance on directions to take after escaping L-Space if you end up in the BP or Sto-Lat libraries.")
--If you land in the Sto Lat library from a gap and want to get out, take the only exit listed until you see multiple exits. Then take the second exit in the list over and over until you see "study". Take that and you are out.
--If you land in CWC while jumping gaps, you are now in a stairway maze with one exit: down. If you want to get out of the cwc library from here, just go d,n,e,u,s,d,s,w,u,w,w,d,d,n,w,n,e,e,n,e,e,n,n,w,w,nw,w,sw,w,s,w
sLoadedMap = ""
sCurrentMap = ""
iCurMap = 0
iCharLocMap = iCurMap
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Wander around (don't keep going in a straight line), look for a 'gap' in the list of exits!")
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "Good luck!")
RetitleWindow(winMinimap, "Depths of L-Space")
return
end
-- Try to find ourselves based on a short title/fake room ID
local objHere = nil
if (sQuowLocationsByShort[sApparentRoomID] ~= nil) then
--Note("Debug: Short location hit?")
objHere = sQuowLocationsByShort[sApparentRoomID]
if (sQuowMapfiles[objHere[1]] ~= nil) then
-- Special Shades handler if we still don't know which shades room we're in
if (iShadesRoom == 18) then
if (sApparentRoomID == "ShadesEntrance") then
iShadesRoom = 17
elseif (sApparentRoomID == "Shades2") then
iShadesRoom = 2
elseif (sApparentRoomID == "Shades5") then
iShadesRoom = 5
elseif (sApparentRoomID == "Shades8") then
iShadesRoom = 8
elseif (sApparentRoomID == "Shades9") then
iShadesRoom = 9
elseif (sApparentRoomID == "Shades12") then
iShadesRoom = 12
elseif (sApparentRoomID == "Shades16") then
iShadesRoom = 16
end
end
sCurrentMap = sQuowMapfiles[objHere[1]][1]
iCurMap = objHere[1]
if (iCurMap == 47 and iOldMap == 12) then
sLastDir = "n"
end
iCharLocMap = iCurMap
iMyX = objHere[2]
iMyY = objHere[3]
iOldMX = iMyX
iOldMY = iMyY
sOldMap = sCurrentMap
iOldMap = iCurMap
iCatchupX = iMyX
iCatchupY = iMyY
sFutureRoomID = "ShortID-" .. sApparentRoomID
end
end
end
-- Try to predict movement from player commands sent for map-tracking
function MinimapHandleMovement(sMovement, bAddQueue)
if (sQuowTrackMoves[sMovement] ~= nil and iCurMap > 0) then
-- Guesstimated movement tracking if we are waiting for a movement
if (sQuowTrackMoves[sMovement][1] == 0 and sQuowTrackMoves[sMovement][2] == 0) then
-- Try to compass convert
if (sLastDir == "n" or sLastDir == "north") then
if (sMovement == "fw" or sMovement == "forward") then
sMovement = "n"
elseif (sMovement == "bw" or sMovement == "backward") then
sMovement = "s"
elseif (sMovement == "lt" or sMovement == "left") then
sMovement = "w"
elseif (sMovement == "rt" or sMovement == "right") then
sMovement = "e"
end
elseif (sLastDir == "e" or sLastDir == "east") then
if (sMovement == "fw" or sMovement == "forward") then
sMovement = "e"
elseif (sMovement == "bw" or sMovement == "backward") then
sMovement = "w"
elseif (sMovement == "lt" or sMovement == "left") then
sMovement = "n"
elseif (sMovement == "rt" or sMovement == "right") then
sMovement = "s"
end
elseif (sLastDir == "s" or sLastDir == "south") then
if (sMovement == "fw" or sMovement == "forward") then
sMovement = "s"
elseif (sMovement == "bw" or sMovement == "backward") then
sMovement = "n"
elseif (sMovement == "lt" or sMovement == "left") then
sMovement = "e"
elseif (sMovement == "rt" or sMovement == "right") then
sMovement = "w"
end
elseif (sLastDir == "w" or sLastDir == "west") then
if (sMovement == "fw" or sMovement == "forward") then
sMovement = "w"
elseif (sMovement == "bw" or sMovement == "backward") then
sMovement = "e"
elseif (sMovement == "lt" or sMovement == "left") then
sMovement = "s"
elseif (sMovement == "rt" or sMovement == "right") then
sMovement = "n"
end
end
end
-- Special Shades directions
if (iShadesRoom >= 1 and iShadesRoom <= 17) then
bAddQueue = false
local sShadesFound = ""
-- Shades numbers input, so calculate new position
if (sQuowTrackMoves[sMovement][1] == 6 and sQuowTrackMoves[sMovement][2] == 6) then
iDestinationRoom = 0
for sRealDirection, sConversionInfo in pairs(sQuowShadesDirections[iShadesRoom]) do
if (sMovement == sConversionInfo[1]) then
sShadesFound = sRealDirection
iDestinationShadesRoom = sConversionInfo[2]
end
end
if (sShadesFound ~= "") then
sMovement = sShadesFound
end
end
end
-- Now handle the movement in relative map-shift terms
sLastDir = sMovement
-- Shift the map as appropriate, if not maplocked
if (bMapLocked == false or bTempUnlocked == true) then
local iShiftX = (sQuowTrackMoves[sMovement][1] * sQuowMapfiles[iCurMap][3])
local iShiftY = (sQuowTrackMoves[sMovement][2] * sQuowMapfiles[iCurMap][4])
-- Special UU library wraparound clause
if (iCurMap == 47) then
if ((iMyX + iShiftX) >= 262) then
iShiftX = iShiftX - 240
elseif ((iMyX + iShiftX) <= 37) then
iShiftX = iShiftX + 240
end
end
-- Are we queueing this move, or doing an instant-shift?
if (bAddQueue == true) then
table.insert (iMapShiftQueue, {iShiftX, iShiftY, true, iCurMap})
iTimeSinceLastMove = os.time()
else
iMyX = iMyX + iShiftX
iMyY = iMyY + iShiftY
end
bTempUnlocked = false
end
-- Now redraw the map in the new location
RedrawMap()
end
end
-- Clear any predicted-movement queues and map shifts
function QuowClearQueues()
for sKey, sShiftData in ipairs(iMapShiftQueue) do
iMapShiftQueue[sKey] = nil
end
if (sQuowLocationsByRoomID[sCurrentRoomID] ~= nil) then
iMyX = sQuowLocationsByRoomID[sCurrentRoomID][2]
iMyY = sQuowLocationsByRoomID[sCurrentRoomID][3]
iOldMX = iMyX
iOldMY = iMyY
--Note("Snapping ourselves back to room ID: " .. sCurrentRoomID .. ", " .. iMyX .. "/" .. iMyY)
if (iCurMap ~= sQuowLocationsByRoomID[sCurrentRoomID][1]) then
iCurMap = sQuowLocationsByRoomID[sCurrentRoomID][1]
iOldMap = iCurMap
iCharLocMap = iCurMap
sCurrentMap = sQuowMapfiles[iCurMap][1]
end
end
end
-- Window resizing to auto-shift minimap window around
bPreInstalled = false
iLastRedrew = 0
iRedrawsLastSecond = 1
function OnPluginWorldOutputResized ()
-- Safety to prevent mass-spam on first launch due to Mushclient still loading and resizing windows, would cause crashes
if (bPreInstalled == true) then
if (iRedrawsLastSecond < 2 or (os.time() - iLastRedrew) > 1) then
iRedrawsLastSecond = iRedrawsLastSecond + 1
if ((os.time() - iLastRedrew) > 2) then
iRedrawsLastSecond = 1
end
iLastRedrew = os.time()
if (iThemeLayoutLocked > 0) then
QuowLayoutTheme(iThemeLayoutLocked)
else
RedoScreenMargins()
end
else
if (iThemeLayoutLocked > 0) then
AddTimer("RedrawTimer", 0, 0, 0.5, "", 17445, "QuowLayoutTheme")
else
AddTimer("RedrawTimer", 0, 0, 0.5, "", 17445, "RedoScreenMargins")
end
end
end
end -- function
-- Check commands preparing for send for special room handlers
function OnPluginSend (sText)
-- Library special position handling
if (bHandlerLib == true and iCurMap == 47 and (sCurrentRoomID == "UULibrary" or sThisRoomTitle == "UULibraryExit" or sThisRoomTitle == "UULibraryGap")) then
local sShortDir = sMovementShort[string.lower(sText)]
local sTransmute = ""
if (sShortDir == "n") then
if (sLastDir == "n") then
sTransmute = "fw"
elseif (sLastDir == "e") then
sTransmute = "lt"
elseif (sLastDir == "s") then
sTransmute = "bw"
elseif (sLastDir == "w") then
sTransmute = "rt"
end
elseif (sShortDir == "e") then
if (sLastDir == "n") then
sTransmute = "rt"
elseif (sLastDir == "e") then
sTransmute = "fw"
elseif (sLastDir == "s") then
sTransmute = "lt"
elseif (sLastDir == "w") then
sTransmute = "bw"
end
elseif (sShortDir == "s") then
-- We're at the very bottom exit room, so pass on a true south exit
if (iMyY >= 4795 and iMyX >= 153 and iMyX <= 177) then
return true
end
if (sLastDir == "n") then
sTransmute = "bw"
elseif (sLastDir == "e") then
sTransmute = "rt"
elseif (sLastDir == "s") then
sTransmute = "fw"
elseif (sLastDir == "w") then
sTransmute = "lt"
end
elseif (sShortDir == "w") then
if (sLastDir == "n") then
sTransmute = "lt"
elseif (sLastDir == "e") then
sTransmute = "bw"
elseif (sLastDir == "s") then
sTransmute = "rt"
elseif (sLastDir == "w") then
sTransmute = "fw"
end
end
if (sTransmute ~= "") then
--Note("Quow's Cow Bar: Converting '" .. sText .. "' to '" .. sTransmute .. "'.")
SendNoEcho(sTransmute)
return false
end
-- Special Shades position handler
elseif (bHandlerSM == true and iShadesRoom >= 1 and iShadesRoom <= 17 and sQuowTrackMoves[string.lower(sText)] ~= nil) then
-- Shades handler
local sShortDir = sMovementShort[string.lower(sText)]
if (sCurrentRoomID == "01bbd8b887e71314d8e358cbaf4f585391206bc4" and sShortDir == "w") then
return true
end
if (sQuowShadesDirections[iShadesRoom][sShortDir] ~= nil) then
--Note("Quow's Cow Bar: Converting '" .. sText .. "' to '" .. sQuowShadesDirections[iShadesRoom][sShortDir][1])
SendNoEcho(sQuowShadesDirections[iShadesRoom][sShortDir][1])
return false
end
end
-- Allow everything else to be sent as a command
return true
end
-- Check what was sent to the mud in plaintext for movement-prediction on the graphical map
sLastSentCommand = ""
function OnPluginSent (sText)
-- Clear the queue if it's been a while since we last saw a room name
if (os.time() - iTimeSinceLastMove >= 10 and #iMapShiftQueue >= 1) then
-- 10 seconds since last move, deleting all queues
QuowClearQueues()
end
-- Store it
sLastSentCommand = sText
-- Check if this command matches a movement direction (strip spaces + lowercase it)
sTemp = sText:match'^%s*(.*%S)' or ''
sTemp = string.lower(sTemp)
if (sMovementShort[sTemp] ~= nil) then
sTemp = sMovementShort[sTemp]
end
local bFoundConnection = false
-- Look for where we're heading
if (sQuowExitsByExit[sFutureRoomID] ~= nil and sQuowExitsByExit[sFutureRoomID][sTemp] ~= nil) then
local sOldFutureID = sFutureRoomID
sFutureRoomID = sQuowExitsByExit[sFutureRoomID][sTemp]
bFoundConnection = true
iMyX = iOldMX
iMyY = iOldMY
local iShiftX = sQuowLocationsByRoomID[sFutureRoomID][2] - sQuowLocationsByRoomID[sOldFutureID][2]
local iShiftY = sQuowLocationsByRoomID[sFutureRoomID][3] - sQuowLocationsByRoomID[sOldFutureID][3]
iCurMap = sQuowLocationsByRoomID[sFutureRoomID][1]
sCurrentMap = sQuowMapfiles[iCurMap][1]
table.insert (iMapShiftQueue, {iShiftX, iShiftY, false, iCurMap})
iTimeSinceLastMove = os.time()
RedrawMap()
end
--Note("Debug: Connection=" .. tostring(bFoundConnection) .. ", predictive=" .. tostring(bPredictiveMoves) .. ", curmap=" .. iCurMap .. ", currentroomid=" .. sCurrentRoomID .. ", stemp=" .. sTemp)
if (bFoundConnection == false and (bPredictiveMoves == true or iCurMap == 8 or iCurMap == 47 or (sCurrentRoomID == "d67e7fc940fa14ae6356389ec1c96cc27ad81391" and sTemp == "n"))) then
MinimapHandleMovement(sTemp, true)
end
end
-- Handle following another player, try to recognise their movements to predict-move on the map
function FollowHandler (sName, sLine, wildcards)
-- Check if this command matches a movement direction
local sTemp = string.lower(wildcards[1])
if (sMovementShort[sTemp] ~= nil) then
sTemp = sMovementShort[sTemp]
sLastDir = sTemp
end
local bFoundConnection = false
-- Look for where we're heading
if (sQuowExitsByExit[sCurrentRoomID] ~= nil and sQuowExitsByExit[sCurrentRoomID][sTemp] ~= nil) then
local sNewFollowID = sQuowExitsByExit[sCurrentRoomID][sTemp]
bFoundConnection = true
local iShiftX = sQuowLocationsByRoomID[sNewFollowID][2] - sQuowLocationsByRoomID[sCurrentRoomID][2]
local iShiftY = sQuowLocationsByRoomID[sNewFollowID][3] - sQuowLocationsByRoomID[sCurrentRoomID][3]
iMyX = iMyX + iShiftX
iMyY = iMyY + iShiftY
RedrawMap()
end
if (bFoundConnection == false and (bPredictiveMoves == true or iCurMap == 8 or iCurMap == 47)) then
MinimapHandleMovement(sTemp, false)
end
Repaint()
end
-- Stopped/movement queue cleared
function MovementQueueClear (sName, sLine, wildcards)
QuowClearQueues()
RedrawMap()
end
-- Movement fail detected (impossible movement)
function MovementFailure (sName, sLine, wildcards)
sLastSentCommand = ""
-- Find the very first pixel-shift guess and remove it?
for iKey, sShiftData in ipairs(iMapShiftQueue) do
if (sShiftData[3] == true) then
local iBadShift = table.remove(iMapShiftQueue, iKey)
RedrawMap()
break
end
end
-- Library directional error reversing
if (iCurMap == 47 and sReverseMove[sLastDir] ~= nil) then
sLastDir = sOldDir
RedrawMap()
end
end
-- Movement blockage detected (valid movement, but something blocked us)
function MovementBlockage (sName, sLine, wildcards)
sLastSentCommand = ""
-- Find the very first pixel-shift guess and remove it?
if (#iMapShiftQueue > 0) then
local iBadShift = table.remove(iMapShiftQueue, iKey)
sFutureRoomID = sCurrentRoomID
RedrawMap()
end
end
-- Log shop inventory to this room ID
function ShopInventory (sName, sLine, wildcards, styles)
if (bCreatingRooms == true) then
if (bLastRoomFailGMCP == false) then
sQuowLocationsByRoomID[sCurrentRoomID][6] = 1
local sStockCode = EscapeSQL(wildcards[1])
local sStockName = EscapeSQL(wildcards[2])
local sStockPrice = EscapeSQL(wildcards[3])
sSQL = "INSERT INTO room_shop VALUES ('" .. sCurrentRoomID .."', '" .. sStockCode .. "', '" .. sStockName .. "', '" .. sStockPrice .. "')"
assert(dbMap:execute(sSQL))
sSQL = "UPDATE rooms SET shop_stocked=1 WHERE room_id='" .. sCurrentRoomID .. "' AND shop_stocked=0"
assert(dbMap:execute(sSQL))
end
end
end
-- Quow's custom path finding/Routefinder
function QuowRoutefind(sStartID, sDestinationID, iDestMap, iDestX, iDestY)
if (sStartID == sDestinationID or sStartID == nil or sDestinationID == nil or sStartID == "" or sDestinationID == "") then
Note("Cannot find a valid route, start or end rooms may be invalid or the same place.")
return "", "", 0
end
local sDoRoom = {}
local bEverDone = {}
local sIDToRoomNum = {}
local iGotHereFrom = {}
sDoRoom[1] = sStartID
sIDToRoomNum[sStartID] = 1
bEverDone[sStartID] = true
local iNextRoom = 1
local iTotalRooms = 1
local sLinkedTo = {}
local iSearchDepth = 0
local bDone = false
local iFinalRoom = 0
local iPreviousTotal = 0
-- "Infinite" loop
while (bDone == false) do
-- Loop through all the rooms we have yet to do
iPreviousTotal = iTotalRooms
for iN = iNextRoom, iPreviousTotal do
-- Loop through all the exits from this room
--Note("Looping through exits of room num " .. iN .. " ['" .. sDoRoom[iN] .. "']")
for sKey, sExitData in pairs(sQuowExitsByID[sDoRoom[iN]]) do
-- Make sure we aren't looping back around on ourselves, and that we haven't already finished
if (sKey ~= sStartID and bEverDone[sKey] == nil and iFinalRoom == 0) then
iTotalRooms = iTotalRooms + 1
-- Add THIS destination of THIS room, to the "to-be-processed" list
sDoRoom[iTotalRooms] = 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
--Note(" " .. sDoRoom[iN] .. " (" .. sQuowLocationsByRoomID[sDoRoom[iN]][4] .. ") connects to " .. sKey .. " (" .. sQuowLocationsByRoomID[sKey][4] .. ") via '" .. sExitData .. "'")
iGotHereFrom[iTotalRooms] = {sIDToRoomNum[sDoRoom[iN]], sExitData}
-- See if we made it yet
if (sDoRoom[iN] == sDestinationID) then
--Note("Found destination...")
bDone = true
iFinalRoom = iN
elseif (sKey == sDestinationID) then
-- Double check
--Note("Special found destination")
bDone = true
iFinalRoom = iTotalRooms
elseif (sQuowLocationsByRoomID[sDoRoom[iN]][1] == iDestMap and sQuowLocationsByRoomID[sDoRoom[iN]][2] == iDestX and sQuowLocationsByRoomID[sDoRoom[iN]][3] == iDestY) then
-- Maybe we reached the co-ordinates instead - eg a house with multiple rooms in one pixels
bDone = true
iFinalRoom = iN
end
end -- Not back to beginning
end -- Loop through exit rooms
end -- Loop through "to-do"
iNextRoom = iPreviousTotal + 1
if (iNextRoom > iTotalRooms) then
Note("Failed to find a route, no solid path all the way to the destination!")
bDone = true
end
iSearchDepth = iSearchDepth + 1
if (iSearchDepth > 500) then
Note("Route finding to target room failed, search depth exceeded the 500 limit")
bDone = true
iFinalRoom = 0
break
end
end
-- Did we actually find a room?
if (iFinalRoom ~= 0) then
sPath = {}
bDone = false
local iCurRoom = iFinalRoom
while (bDone == false) do
--Note("iCurRoom=" .. iCurRoom .. "... GotHereFrom:" .. iGotHereFrom[iCurRoom][1] .. " with " .. iGotHereFrom[iCurRoom][2])
table.insert(sPath, iGotHereFrom[iCurRoom][2])
iCurRoom = iGotHereFrom[iCurRoom][1]
if (iCurRoom == 1) then
bDone = true
end
end
local sRealPath = ""
for iN = #sPath, 1, -1 do
if (sRealPath ~= "") then
sRealPath = sRealPath .. ";"
end
sRealPath = sRealPath .. sPath[iN]
end
return sRealPath, sDoRoom[iFinalRoom], #sPath
end
-- Didn't find a route, return blanks
return "", "", 0
end
-- Convert mouseclicks on the minimap to a location to shift the map around
iCatchupX = 0
iCatchupY = 0
--Mousemapping
function QuowMapMouse(flags, hotspot_id)
if (hotspot_id == "hsMapClick") then
if (bit.band(flags, miniwin.hotspot_got_alt) ~= 0) then
-- Alt-click cycles through all the maps, left click one way, right click the other
if (bit.band(flags, miniwin.hotspot_got_lh_mouse) ~= 0) then
iCurMap = iCurMap + 1
if (iCurMap > #sQuowMapfiles) then
iCurMap = 1
end
else
iCurMap = iCurMap - 1
if (iCurMap < 1) then
iCurMap = #sQuowMapfiles
end
end
sCurrentMap = sQuowMapfiles[iCurMap][1]
iMyX = sQuowMapfiles[iCurMap][5]
iMyY = sQuowMapfiles[iCurMap][6]
Note("Changing map to: " .. sCurrentMap)
RedrawMap()
Repaint()
--or bit.band(flags, miniwin.hotspot_got_shift) ~= 0
elseif (bit.band(flags, miniwin.hotspot_got_rh_mouse) ~= 0) then
-- Right click bring up menu - build the custom menu here
-- ! : return numeric result (only in first position of entire string)
-- - : separator line
-- ^ : grayed-out item
-- + : checked (ticked) item
-- > : start of nested menu (rest of line is nested menu title)
-- < : end of nested menu (rest of line is ignored)
local sMenuString = "^Quow's Cow Bar:|-|"
if (WINDATA[winMinimap]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Minimap Window Position|"
sMenuString = sMenuString .. "Hide Minimap Window|"
-- Options section
sMenuString = sMenuString .. ">Minimap Options...|"
sMenuString = sMenuString .. ">Brightness...|"
if (iMinimapBrightness == 100) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Brightness: 100%|"
if (iMinimapBrightness == 90) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Brightness: 90%|"
if (iMinimapBrightness == 80) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Brightness: 80%|"
if (iMinimapBrightness == 70) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Brightness: 70%|"
if (iMinimapBrightness == 60) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Brightness: 60%|"
if (iMinimapBrightness == 50) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Brightness: 50%|"
sMenuString = sMenuString .. "<|"
if (bShowDiscDate == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show Discworld Date on Map|"
if (bDrawOrbs == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Display spell orbs in library|"
if (bDrawSkeletonMode == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Skeleton Map Mode|"
if (bHideOnTerrain == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Auto-hide map in terrains|"
if (bAutoShowHideAscii == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Auto-Hide-Show ASCII map with terrains|"
if (bAsciiMapOmitted == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Omit ASCII map from MUD output|"
if (bShowGhost == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show Ghost when running ahead|"
if (bPredictiveMoves == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Allow map to move into unknown rooms|"
sMenuString = sMenuString .. "<|"
-- Windows section
sMenuString = sMenuString .. ">Extra Windows...|"
if (WINDATA[winBars]["SHOW"] == true) then
sMenuString = sMenuString .. "+"
end
if (MODULES["vitals"] == false) then
sMenuString = sMenuString .. "^[disabled] "
end
sMenuString = sMenuString .. "Show Character Vitals Window|"
if (WINDATA[winXP]["SHOW"] == true) then
sMenuString = sMenuString .. "+"
end
if (MODULES["xp"] == false) then
sMenuString = sMenuString .. "^[disabled] "
end
sMenuString = sMenuString .. "Show XP Window|"
if (WINDATA[winMDT]["SHOW"] == true) then
sMenuString = sMenuString .. "+"
end
if (MODULES["mdt"] == false) then
sMenuString = sMenuString .. "^[disabled] "
end
sMenuString = sMenuString .. "Show Written-Map Window|"
if (WINDATA[winAscii]["SHOW"] == true) then
sMenuString = sMenuString .. "+"
end
if (MODULES["ascii"] == false) then
sMenuString = sMenuString .. "^[disabled] "
end
sMenuString = sMenuString .. "Show Ascii-Map Window|"
if (WINDATA[winStats]["SHOW"] == true) then
sMenuString = sMenuString .. "+"
end
if (MODULES["stats"] == false) then
sMenuString = sMenuString .. "^[disabled] "
end
sMenuString = sMenuString .. "Show Combat Stats Window|"
if (WINDATA[winShields]["SHOW"] == true) then
sMenuString = sMenuString .. "+"
end
if (MODULES["shields"] == false) then
sMenuString = sMenuString .. "^[disabled] "
end
sMenuString = sMenuString .. "Show Shields Window|"
if (WINDATA[winComms]["SHOW"] == true) then
sMenuString = sMenuString .. "+"
end
if (MODULES["comms"] == false) then
sMenuString = sMenuString .. "^[disabled] "
end
sMenuString = sMenuString .. "Show Comms Window|"
sMenuString = sMenuString .. "<|"
-- Disable Modules
sMenuString = sMenuString .. ">Disable/Enable Modules...|"
if (MODULES["stats"] == true) then
sMenuString = sMenuString .. "+Disable Combat Stats Module|"
else
sMenuString = sMenuString .. "Enable Combat Stats Module|"
end
if (MODULES["mdt"] == true) then
sMenuString = sMenuString .. "+Disable Written-Map Module|"
else
sMenuString = sMenuString .. "Enable Written-Map Module|"
end
if (MODULES["ascii"] == true) then
sMenuString = sMenuString .. "+Disable Ascii-Map Module|"
else
sMenuString = sMenuString .. "Enable Ascii-Map Module|"
end
if (MODULES["comms"] == true) then
sMenuString = sMenuString .. "+Disable Comms Module|"
else
sMenuString = sMenuString .. "Enable Comms Module|"
end
if (MODULES["shields"] == true) then
sMenuString = sMenuString .. "+Disable Shields Module|"
else
sMenuString = sMenuString .. "Enable Shields Module|"
end
if (MODULES["xp"] == true) then
sMenuString = sMenuString .. "+Disable XP Module|"
else
sMenuString = sMenuString .. "Enable XP Module|"
end
if (MODULES["vitals"] == true) then
sMenuString = sMenuString .. "+Disable Character Vitals Module|"
else
sMenuString = sMenuString .. "Enable Character Vitals Module|"
end
sMenuString = sMenuString .. "<|"
-- Screen margins
sMenuString = sMenuString .. ">Screen Margins...|"
if (bLockMargins == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Screen Margins|-|"
if (SCREENMARGINS["left"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Left Edge Margin|"
if (SCREENMARGINS["top"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Top Edge Margin|"
if (SCREENMARGINS["right"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Right Edge Margin|"
if (SCREENMARGINS["bottom"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Bottom Edge Margin|"
sMenuString = sMenuString .. "<|"
-- Instant layouts
sMenuString = sMenuString .. ">Instant Layouts...|"
sMenuString = sMenuString .. "^Auto-Configure Full Layout:|-|"
if (iThemeLayoutLocked == 11) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Simple Cow|-|"
if (iThemeLayoutLocked == 2) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Left|"
if (iThemeLayoutLocked == 3) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Right|"
if (iThemeLayoutLocked == 1) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Top|"
if (iThemeLayoutLocked == 4) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Bottom|"
sMenuString = sMenuString .. "-|"
if (iThemeLayoutLocked == 8) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Semi-Skimmed Top|"
if (iThemeLayoutLocked == 9) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Semi-Skimmed Bottom|"
sMenuString = sMenuString .. "-|"
if (iThemeLayoutLocked == 5) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Micro-Cow Miniatures|"
if (iThemeLayoutLocked == 7) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Marginalised Cows|"
if (iThemeLayoutLocked == 6) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Big-Cows Big-Windows|"
sMenuString = sMenuString .. "-|"
if (iThemeLayoutLocked == 10) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Load Custom Cows Layout|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Save Custom Cows Layout|"
sMenuString = sMenuString .. "<|-|"
-- Switch to map section
sMenuString = sMenuString .. "Switch To Map|-|"
-- Basic functionality
if (iMyX == iOldMX and iMyY == iOldMY and iCurMap == iOldMap) then
sMenuString = sMenuString .. "^"
end
sMenuString = sMenuString .. "Reset Map Position|"
sMenuString = sMenuString .. "List Bookmarked Rooms|"
sMenuString = sMenuString .. "-|"
-- Room-click functionatliy
if (sClickedRoomID == "") then
sMenuString = sMenuString .. "^Left-click a valid room first:|"
sMenuString = sMenuString .. "^Add Clicked Room To Bookmarks|"
sMenuString = sMenuString .. "^Show Clicked Room Info|"
sMenuString = sMenuString .. "^Speedwalk To Clicked Room|"
else
if (sQuowUserBookmarks[sClickedRoomID] ~= nil and sQuowUserBookmarks[sClickedRoomID] ~= "") then
sMenuString = sMenuString .. "^" .. sQuowUserBookmarks[sClickedRoomID] .. ":|"
else
sMenuString = sMenuString .. "^" .. sQuowLocationsByRoomID[sClickedRoomID][4] .. ":|"
end
if (sQuowUserBookmarks[sClickedRoomID] == nil) then
sMenuString = sMenuString .. "Add Clicked Room To Bookmarks|"
else
sMenuString = sMenuString .. "Remove Clicked Room From Bookmarks|"
end
sMenuString = sMenuString .. "Show Clicked Room Info|"
sMenuString = sMenuString .. "Speedwalk To Clicked Room|"
end
sRMBResult = WindowMenu (winMinimap, WindowInfo(winMinimap, 14), WindowInfo(winMinimap, 15), sMenuString)
if (sRMBResult ~= "") then
if (sRMBResult == "Reset Map Position") then
QuowOldSnap()
-- Lock minimap window Position
elseif (sRMBResult == "Lock Minimap Window Position") then
if (WINDATA[winMinimap]["LOCKED"] == true) then
WINDATA[winMinimap]["LOCKED"] = false
else
WINDATA[winMinimap]["LOCKED"] = true
end
elseif (sRMBResult == "Hide Minimap Window") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Hiding the minimap window. Use '", sGlobalColourCyan, sGlobalColourBlack, "minimap show", sGlobalColourOrange, sGlobalColourBlack, "' to display again.")
ColourTell(sGlobalColourSilver, sGlobalColourBlack, "(or ")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winMinimap .. ")", "Click Here", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " to show it again)")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Note: MANY options and features of Cow Bar are controlled through the minimap window menu!")
WindowShow(winMinimap, false)
WINDATA[winMinimap]["SHOW"] = false
iThemeLayoutLocked = 0
bMinimapHidden = true
bMinimapTempHidden = false
-- Pre-configured layout themes
elseif (sRMBResult == "Simple Cow") then
QuowLayoutTheme(11)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Top") then
QuowLayoutTheme(1)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Left") then
QuowLayoutTheme(2)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Right") then
QuowLayoutTheme(3)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Bottom") then
QuowLayoutTheme(4)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Micro-Cow Miniatures") then
QuowLayoutTheme(5)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Big-Cows Big-Windows") then
QuowLayoutTheme(6)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Marginalised Cows") then
QuowLayoutTheme(7)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Semi-Skimmed Top") then
QuowLayoutTheme(8)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Semi-Skimmed Bottom") then
QuowLayoutTheme(9)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Load Custom Cows Layout") then
QuowLayoutTheme(10)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: Custom Cows")
elseif (sRMBResult == "Save Custom Cows Layout") then
CallPlugin ("bfe35205f026786ea1d56e3b", "QuowSaveCustomCows", "", "")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your current exact window positions and sizes have been saved to the Custom Cows layout.")
elseif (sRMBResult == "List Bookmarked Rooms") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar Location Bookmarks:")
local iAnyBookmarks = QuowBookmarkList("")
if (iAnyBookmarks == 0) then
Note("You have no bookmarked rooms. You can create these by left-clicking a room on the map, and then selecting Bookmark in the right-click menu.")
end
elseif (sRMBResult == "Auto-hide map in terrains") then
if (bHideOnTerrain == true) then
bHideOnTerrain = false
else
bHideOnTerrain = true
end
elseif (sRMBResult == "Auto-Hide-Show ASCII map with terrains") then
if (bAutoShowHideAscii == true) then
bAutoShowHideAscii = false
else
bAutoShowHideAscii = true
end
elseif (sRMBResult == "Omit ASCII map from MUD output") then
if (bAsciiMapOmitted == true) then
bAsciiMapOmitted = false
else
bAsciiMapOmitted = true
end
elseif (sRMBResult == "Draw spell orbs in library") then
if (bDrawOrbs == true) then
bDrawOrbs = false
else
bDrawOrbs = true
end
elseif (sRMBResult == "Show Ghost when running ahead") then
if (bShowGhost == true) then
bShowGhost = false
else
bShowGhost = true
end
elseif (sRMBResult == "Brightness: 100%") then
iMinimapBrightness = 100
RedrawMap()
Repaint()
elseif (sRMBResult == "Brightness: 90%") then
iMinimapBrightness = 90
RedrawMap()
Repaint()
elseif (sRMBResult == "Brightness: 80%") then
iMinimapBrightness = 80
RedrawMap()
Repaint()
elseif (sRMBResult == "Brightness: 70%") then
iMinimapBrightness = 70
RedrawMap()
Repaint()
elseif (sRMBResult == "Brightness: 60%") then
iMinimapBrightness = 60
RedrawMap()
Repaint()
elseif (sRMBResult == "Brightness: 50%") then
iMinimapBrightness = 50
RedrawMap()
Repaint()
elseif (sRMBResult == "Show Discworld Date on Map") then
if (bShowDiscDate == true) then
bShowDiscDate = false
RedrawMap()
else
bShowDiscDate = true
RedrawMap()
end
elseif (sRMBResult == "Skeleton Map Mode") then
if (bDrawSkeletonMode == true) then
bDrawSkeletonMode = false
else
bDrawSkeletonMode = true
end
elseif (sRMBResult == "Allow map to move into unknown rooms") then
if (bPredictiveMoves == true) then
bPredictiveMoves = false
else
bPredictiveMoves = true
end
elseif (sRMBResult == "Show XP Window") then
if (WINDATA[winXP]["SHOW"] == true) then
WINDATA[winXP]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winXP, false)
else
WINDATA[winXP]["SHOW"] = true
WindowShow(winXP, true)
RedrawXPWindow(true)
end
elseif (sRMBResult == "Show Character Vitals Window") then
if (WINDATA[winBars]["SHOW"] == true) then
WINDATA[winBars]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winBars, false)
else
WINDATA[winBars]["SHOW"] = true
WindowShow(winBars, true)
RedrawVitalsWindow()
end
elseif (sRMBResult == "Show Written-Map Window") then
if (WINDATA[winMDT]["SHOW"] == true) then
WINDATA[winMDT]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winMDT, false)
else
WINDATA[winMDT]["SHOW"] = true
WindowShow(winMDT, true)
RedrawMDTWindow()
end
elseif (sRMBResult == "Show Combat Stats Window") then
if (WINDATA[winStats]["SHOW"] == true) then
WINDATA[winStats]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winStats, false)
else
WINDATA[winStats]["SHOW"] = true
WindowShow(winStats, true)
RedrawStatsWindow()
end
elseif (sRMBResult == "Show Shields Window") then
if (WINDATA[winShields]["SHOW"] == true) then
WINDATA[winShields]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winShields, false)
else
WINDATA[winShields]["SHOW"] = true
WindowShow(winShields, true)
RedrawShieldsWindow()
end
elseif (sRMBResult == "Show Comms Window") then
if (WINDATA[winComms]["SHOW"] == true) then
WINDATA[winComms]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winComms, false)
else
WINDATA[winComms]["SHOW"] = true
WindowShow(winComms, true)
bCommsNeedsButtons = true
RedrawCommsWindow()
end
elseif (sRMBResult == "Show Ascii-Map Window") then
if (WINDATA[winAscii]["SHOW"] == true) then
WINDATA[winAscii]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winAscii, false)
else
WINDATA[winAscii]["SHOW"] = true
WindowShow(winAscii, true)
RedrawAsciiWindow()
end
-- ***** Disable Modules Fully *****
elseif (sRMBResult == "Disable Character Vitals Module") then
MODULES["vitals"] = false
WINDATA[winBars]["SHOW"] = false
WindowShow(winBars, false)
EnableTriggerGroup ("module_vitals", false)
EnableTimer("timer_gpregen", false)
ColourNote(sGlobalColourRed, sGlobalColourBlack, "Character Vitals Module Disabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Your HP, GP, and Burden will not be logged. There will be no GP-Full notifications.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a VERY MINOR (~1%) impact on plugin overhead. You can re-enable the module in the main minimap right-click menu.")
elseif (sRMBResult == "Enable Character Vitals Module") then
MODULES["vitals"] = true
WINDATA[winBars]["SHOW"] = true
WindowShow(winBars, true)
RedrawVitalsWindow()
EnableTriggerGroup ("module_vitals", true)
EnableTimer("timer_gpregen", true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Character Vitals Module Enabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a VERY MINOR (~1%) impact on plugin overhead.")
elseif (sRMBResult == "Disable XP Module") then
MODULES["xp"] = false
WINDATA[winXP]["SHOW"] = false
WindowShow(winXP, false)
EnableTriggerGroup ("module_xp", false)
EnableTimer("timer_xpgraph", false)
ColourNote(sGlobalColourRed, sGlobalColourBlack, "XP Module Disabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Your XP rates will not be logged. You cannot group-report your XP-rates.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a VERY MINOR (~1%) impact on plugin overhead. You can re-enable the module in the main minimap right-click menu.")
elseif (sRMBResult == "Enable XP Module") then
MODULES["xp"] = true
WINDATA[winXP]["SHOW"] = true
WindowShow(winXP, true)
RedrawXPWindow(true)
EnableTriggerGroup ("module_xp", true)
EnableTimer("timer_xpgraph", true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "XP Module Enabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a VERY MINOR (~1%) impact on plugin overhead.")
elseif (sRMBResult == "Disable Written-Map Module") then
MODULES["mdt"] = false
WINDATA[winMDT]["SHOW"] = false
WindowShow(winMDT, false)
EnableTriggerGroup ("module_mdt", false)
ColourNote(sGlobalColourRed, sGlobalColourBlack, "Written-Map Module Disabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "You will not see a short-range written-map every time you enter a room.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead. You can re-enable the module in the main minimap right-click menu.")
elseif (sRMBResult == "Enable Written-Map Module") then
MODULES["mdt"] = true
WINDATA[winMDT]["SHOW"] = true
WindowShow(winMDT, true)
RedrawMDTWindow()
EnableTriggerGroup ("module_mdt", true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Written-Map Module Enabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead.")
elseif (sRMBResult == "Disable Ascii-Map Module") then
MODULES["ascii"] = false
WINDATA[winAscii]["SHOW"] = false
WindowShow(winAscii, false)
EnableTriggerGroup ("module_ascii", false)
ColourNote(sGlobalColourRed, sGlobalColourBlack, "Ascii-Map Module Disabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "The Ascii-Map sent by the MUD will not be copied into a window. Ascii-Maps will not automatically pop-up, or hide, in terrains.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead. You can re-enable the module in the main minimap right-click menu.")
elseif (sRMBResult == "Enable Ascii-Map Module") then
MODULES["ascii"] = true
WINDATA[winAscii]["SHOW"] = true
WindowShow(winAscii, true)
RedrawAsciiWindow()
EnableTriggerGroup ("module_ascii", true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Ascii-Map Module Enabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead.")
elseif (sRMBResult == "Disable Combat Stats Module") then
MODULES["stats"] = false
WINDATA[winStats]["SHOW"] = false
CallPlugin ("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
WindowShow(winStats, false)
EnableTriggerGroup ("module_stats", false)
EnableTrigger("QuowStatOptimizer", false)
ColourNote(sGlobalColourRed, sGlobalColourBlack, "Stats Module Disabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Your combat messages will not be coloured or omitted based on categories. No combat stats will be recorded. You cannot generate combat-stat reports.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MODERATE (~50%) impact on plugin overhead. You can re-enable the module in the main minimap right-click menu.")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "If you want to keep the stats module, but find your MUSHclient to be too sluggish with stats enabled, have you tried the 'Optimize Combat Stats Triggers' option in the stats window menu?")
elseif (sRMBResult == "Enable Combat Stats Module") then
MODULES["stats"] = true
WINDATA[winStats]["SHOW"] = true
CallPlugin ("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
WindowShow(winStats, true)
RedrawStatsWindow()
EnableTriggerGroup ("module_stats", true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Stats Module Enabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MODERATE (~50%) impact on plugin overhead.")
if (bOptimisedCombatTriggers == true and iMushclientVersion >= 4.89) then
EnableTrigger("QuowStatOptimizer", true)
else
EnableTrigger("QuowStatOptimizer", false)
end
elseif (sRMBResult == "Disable Shields Module") then
MODULES["shields"] = false
WINDATA[winShields]["SHOW"] = false
WindowShow(winShields, false)
EnableTriggerGroup ("module_shields", false)
ColourNote(sGlobalColourRed, sGlobalColourBlack, "Shields Module Disabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Your shield status will not be monitored. Your group member shields will not be monitored. You cannot see group shields instantly, or generate group-kill reports.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead. You can re-enable the module in the main minimap right-click menu.")
elseif (sRMBResult == "Enable Shields Module") then
MODULES["shields"] = true
WINDATA[winShields]["SHOW"] = true
WindowShow(winShields, true)
RedrawShieldsWindow()
EnableTriggerGroup ("module_shields", true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Shields Module Enabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead.")
elseif (sRMBResult == "Disable Comms Module") then
MODULES["comms"] = false
WINDATA[winComms]["SHOW"] = false
WindowShow(winComms, false)
sCommsBuffer = {}
for sKey, sData in pairs(iCommsCountByType) do
iCommsCountByType[sKey] = 0
end
iCommsMessagesCurrentlyShown = 0
iCurrentChannelChoice = 1
EnableTriggerGroup ("module_comms", false)
ColourNote(sGlobalColourRed, sGlobalColourBlack, "Comms Module Disable:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Tells, group says, and talker channels will not be monitored, recorded, or displayed in a communications window.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead.")
ColourNote(sGlobalColourGreen, sGlobalColourBlack, "IMPORTANT NOTE:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "The Comms Module being enabled actually IMPROVES speed, and LOWERS overhead, if you have the Stats Module enabled, due to the nature of the triggers involved.")
elseif (sRMBResult == "Enable Comms Module") then
MODULES["comms"] = true
WINDATA[winComms]["SHOW"] = true
sCommsBuffer = {}
iCommsCountByType = {}
iChatExtraChannels = 0
iCurrentChannelChoice = 1
for sKey, sData in pairs(objChatFilters) do
iCommsCountByType[sKey] = 0
objChatFilters[sKey][2] = true
iChatExtraChannels = iChatExtraChannels + 1
end
iCommsMessagesCurrentlyShown = 0
WindowShow(winComms, true)
bCommsNeedsButtons = true
RedrawCommsWindow()
EnableTriggerGroup ("module_comms", true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Comms Module Enabled:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This module has a MINOR (~5%) impact on plugin overhead.")
ColourNote(sGlobalColourGreen, sGlobalColourBlack, "IMPORTANT NOTE:")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "The Comms Module being enabled actually IMPROVES speed, and LOWERS overhead, if you have the Stats Module enabled, due to the nature of the triggers involved.")
elseif (sRMBResult == "Lock Screen Margins") then
if (bLockMargins == true) then
Note("Screen margins are unlocked, you can now click-drag to resize your screen areas.")
bLockMargins = false
WindowShow(winScreenMarginLeft, true)
WindowShow(winScreenMarginTop, true)
WindowShow(winScreenMarginRight, true)
WindowShow(winScreenMarginBottom, true)
else
Note("Screen margins are now locked in place.")
bLockMargins = true
WindowShow(winScreenMarginLeft, false)
WindowShow(winScreenMarginTop, false)
WindowShow(winScreenMarginRight, false)
WindowShow(winScreenMarginBottom, false)
end
elseif (sRMBResult == "Left Edge Margin") then
if (SCREENMARGINS["left"][1] == true) then
SCREENMARGINS["left"][1] = false
WindowShow(winScreenMarginLeft, false)
else
SCREENMARGINS["left"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginLeft, true)
end
end
RedoScreenMargins()
elseif (sRMBResult == "Top Edge Margin") then
if (SCREENMARGINS["top"][1] == true) then
SCREENMARGINS["top"][1] = false
WindowShow(winScreenMarginTop, false)
else
SCREENMARGINS["top"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginTop, true)
end
end
RedoScreenMargins()
elseif (sRMBResult == "Right Edge Margin") then
if (SCREENMARGINS["right"][1] == true) then
SCREENMARGINS["right"][1] = false
WindowShow(winScreenMarginRight, false)
else
SCREENMARGINS["right"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginRight, true)
end
end
RedoScreenMargins()
elseif (sRMBResult == "Bottom Edge Margin") then
if (SCREENMARGINS["bottom"][1] == true) then
SCREENMARGINS["bottom"][1] = false
WindowShow(winScreenMarginBottom, false)
else
SCREENMARGINS["bottom"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginBottom, true)
end
end
RedoScreenMargins()
elseif (sRMBResult == "Add Clicked Room To Bookmarks" and sClickedRoomID ~= "") then
QuowCreateBookmark(sClickedRoomID)
elseif (sRMBResult == "Remove Clicked Room From Bookmarks" and sClickedRoomID ~= "") then
QuowDeleteBookmark(sClickedRoomID)
elseif (sRMBResult == "Show Clicked Room Info" and sClickedRoomID ~= "") then
QuowShowRoomInfo(sClickedRoomID)
elseif (sRMBResult == "Speedwalk To Clicked Room" and sClickedRoomID ~= "") then
iMyX = iOldMX
iMyY = iOldMY
iCurMap = iOldMap
sCurrentMap = sOldMap
if (sClickedRoomID ~= "") then
if (sQuowLocationsByRoomID[sClickedRoomID] ~= nil) then
QuowRouteToRoomID(sClickedRoomID, true)
else
Note("Unable to find a route - ensure you click on a recognised room on the map first.")
end
else
Note("Unable to find a route - ensure you click on a recognised room on the map first.")
end
elseif (sRMBResult == "Switch To Map") then
local sMapChoices = {}
for iN = 1, #sQuowMapfiles do
sMapChoices[iN] = sQuowMapfiles[iN][2]
end
local sMapSwitchChoice = utils.listbox("Select a map to switch to.\n", "Map Selection:", sMapChoices, iCurMap)
if (sMapSwitchChoice ~= nil) then
if (sQuowMapfiles[tonumber(sMapSwitchChoice)] ~= nil) then
iCurMap = tonumber(sMapSwitchChoice)
sCurrentMap = sQuowMapfiles[iCurMap][1]
iMyX = sQuowMapfiles[iCurMap][5]
iMyY = sQuowMapfiles[iCurMap][6]
-- get a room ID if one matches this exact co-ordinate
sSQL = "SELECT room_id, map_id, xpos, ypos, room_short, room_type FROM rooms WHERE map_id=" .. iCurMap .. " AND xpos=" .. iMyX .. " AND ypos=" .. iMyY
for row in dbMap:nrows(sSQL) do
sClickedRoomID = row.room_id
break
end
RedrawMap()
Note("Changing map to: " .. sQuowMapfiles[iCurMap][2] .. " (" .. sQuowMapfiles[iCurMap][1] .. ")")
end
end
end
end
else
-- Anything else re-centres the map
local iMouseX = (WindowInfo(winMinimap, 14) - MINIMAP_CX) - 1
local iMouseY = (WindowInfo(winMinimap, 15) - MINIMAP_CY) - 1
if (bRecordingHotzones == true and bit.band(flags, miniwin.hotspot_got_shift) == 0) then
if (iHotspotLevel == 1) then
Note("Recorded one corner of a new hotzone area, now click the opposite corner...")
iTempZone[1] = iCurMap
iTempZone[2] = (iMyX + iMouseX)
iTempZone[3] = (iMyY + iMouseY)
iHotspotLevel = iHotspotLevel + 1
return
elseif (iHotspotLevel == 2) then
Note("Recorded area of the new hotzone, now click on a room to jump to. You can shift-click around the map without selecting a room, and switch to a map in the right click menu first.")
if ((iMyX + iMouseX) < iTempZone[2]) then
iTempZone[4] = iTempZone[2]
iTempZone[2] = (iMyX + iMouseX)
else
iTempZone[4] = (iMyX + iMouseX)
end
if ((iMyY + iMouseY) < iTempZone[3]) then
iTempZone[5] = iTempZone[3]
iTempZone[3] = (iMyY + iMouseY)
else
iTempZone[5] = (iMyY + iMouseY)
end
iHotspotLevel = iHotspotLevel + 1
return
end
end
iMyX = (iMyX + iMouseX)
iMyY = (iMyY + iMouseY)
--Note("Debug: Mouse Translation MX=" .. iMyX .. ", MY=" .. iMyY)
-- Holding shift, skip out before doing anything else!
if (bRecordingHotzones == true and bit.band(flags, miniwin.hotspot_got_shift) ~= 0) then
RedrawMap()
Repaint()
return
end
-- Check a hotspot
if (bit.band(flags, miniwin.hotspot_got_shift) ~= 0) then
for iHotID, sHotData in ipairs(sQuowHotZones) do
--Note("Checking hotzone " .. iHotID)
if (iCurMap == sHotData[1] and iMyX >= sHotData[2] and iMyX <= sHotData[4] and iMyY >= sHotData[3] and iMyY <= sHotData[5]) then
--Note("Debug: Hotzone match! Hotzone #" .. iHotID)
sClickedRoomID = sHotData[6]
iCurMap = sQuowLocationsByRoomID[sClickedRoomID][1]
sCurrentMap = sQuowMapfiles[iCurMap][1]
iMyX = sQuowLocationsByRoomID[sClickedRoomID][2]
iMyY = sQuowLocationsByRoomID[sClickedRoomID][3]
RedrawMap()
Repaint()
return
end
end
end
sClickedRoomID = ""
-- Find a database entry for nearest room to snapto and search from, if not ctrl-clicking
if (bCreatingRooms == false or (bCreatingRooms == true and bit.band(flags, miniwin.hotspot_got_control) == 0)) then
if (sQuowMapfiles[iCurMap] ~= nil) then
local iGridX = sQuowMapfiles[iCurMap][3]
local iGridY = sQuowMapfiles[iCurMap][4]
local iBestDistance = 500
local iThisDistance = 0
local iDistX = 0
local iDistY = 0
local iRealX = iMyX
local iRealY = iMyY
sSQL = "SELECT room_id, map_id, xpos, ypos, room_short, room_type FROM rooms WHERE map_id=" .. iCurMap ..
" AND xpos>=" .. (iMyX-iGridX) .. " AND xpos<=" .. (iMyX+iGridX) ..
" AND ypos>=" .. (iMyY-iGridY) .. " AND ypos<=" .. (iMyY+iGridY)
for row in dbMap:nrows(sSQL) do
iDistX = math.abs(iRealX - row.xpos)
iDistY = math.abs(iRealY - row.ypos)
iThisDistance = math.sqrt((iDistX * iDistX) + (iDistY * iDistY))
if (iThisDistance < iBestDistance) then
iBestDistance = iThisDistance
iMyX = row.xpos
iMyY = row.ypos
sClickedRoomID = row.room_id
end
end
else
ColourNote(iGlobalColourOrange, sGlobalColourBlack, "There seems to be an error in your CowBar install. The saved variable CurMap is set to: " .. tostring(iCurMap) .. ". Attempting to fix this error automatically.")
iCurMap = 1
iOldMap = 1
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "This error occurred in the function 'QuowMapMouse', and the plugin thinks you were trying to click on the graphical minimap at the time this error happened.")
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "The map IDs have now been reset, which may fix this error. You may now try clicking on the graphical map again.")
RedrawMap()
Repaint()
end
end
if (sClickedRoomID ~= "" and bRecordingHotzones == true) then
--Note("Debug Room ID: '" .. sClickedRoomID .. "' : " .. sQuowLocationsByRoomID[sClickedRoomID][1] .. ", " .. sQuowLocationsByRoomID[sClickedRoomID][2] .. ", " .. sQuowLocationsByRoomID[sClickedRoomID][3])
if (iHotspotLevel == 3) then
iTempZone[6] = sClickedRoomID
local sThisLine = "{" .. iTempZone[1] .. ", " .. iTempZone[2] .. ", " .. iTempZone[3] .. ", " .. iTempZone[4] .. ", " .. iTempZone[5] .. ", '" .. iTempZone[6] .. "'}, -- " .. sQuowMapfiles[iTempZone[1]][2] .. " to " .. sQuowMapfiles[sQuowLocationsByRoomID[sClickedRoomID][1]][2] .. "(" .. sQuowLocationsByRoomID[sClickedRoomID][4] .. ")\n"
Note(sThisLine)
SetClipboard(sThisLine)
sQuowHotZones[iCurrentHotspot] = {iTempZone[1], iTempZone[2], iTempZone[3], iTempZone[4], iTempZone[5], iTempZone[6]}
iCurrentHotspot = #sQuowHotZones + 1
iHotspotLevel = 0
bRecordingHotzones = false
Note("Hotzone has been recorded and added to your clipboard. This line must be added to the .xml plugin file in the list of hotzones.")
end
end
-- Try to find a route if ctrl-clicking (and if not in editor-mode)?
if (bCreatingRooms == false and bit.band(flags, miniwin.hotspot_got_control) ~= 0) then
iMyX = iOldMX
iMyY = iOldMY
iCurMap = iOldMap
sCurrentMap = sOldMap
if (sClickedRoomID ~= "") then
if (sQuowLocationsByRoomID[sClickedRoomID] ~= nil) then
QuowRouteToRoomID(sClickedRoomID, false)
else
Note("Unable to find a route - ensure you click on a recognised room on the map first.")
end
else
Note("Unable to find a route - ensure you click on a recognised room on the map first.")
end
end
end
RedrawMap()
Repaint()
end
end
-- Temporary hotspot creator
iHotspotLevel = 0
iCurrentHotspot = #sQuowHotZones + 1
iTempZone = {}
function QuowHotspotStart()
if (bRecordingHotzones == true) then
Note("Starting hotspot record... click top-left, then bottom-right, of square... then go to a room and snap-to it to complete!")
iTempZone = nil
iTempZone = {}
iHotspotLevel = 1
end
end
function QuowBookmarkList(sSearchPhrase)
local iBookmarkFinds = 0
--[[
for row in dbUserData:nrows("SELECT room_id, note FROM bookmarks ORDER BY note asc") do
if (sQuowLocationsByRoomID[row.room_id] ~= nil) then
sQuowUserBookmarks[row.room_id] = row.note
table.insert(sSortedBookmarks, {row.room_id, row.note})
end
end
table.sort(sSortedBookmarks, QuowBookmarkCompare)
--]]
for _, sBookmarkData in pairs(sSortedBookmarks) do
sBookmarkedRoomID = sBookmarkData[1]
sBookmarkNote = sBookmarkData[2]
if (sSearchPhrase == "" or ((sBookmarkNote == "" and string.find(string.lower(sQuowLocationsByRoomID[sBookmarkedRoomID][4]), sSearchPhrase, 1, true) ~= nil) or (sBookmarkNote ~= "" and string.find(string.lower(sBookmarkNote), sSearchPhrase, 1, true) ~= nil))) then
iBookmarkFinds = iBookmarkFinds + 1
Tell("[")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowJumpToRoomID(" .. sBookmarkedRoomID .. ")", "Show", "Display this location (" .. sQuowLocationsByRoomID[sBookmarkedRoomID][1] .. "," .. sQuowLocationsByRoomID[sBookmarkedRoomID][2] .. "," .. sQuowLocationsByRoomID[sBookmarkedRoomID][3] .. ") on the minimap", sGlobalColourOrange, "", 0)
Tell(" | ")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowRouteToRoomID(" .. sBookmarkedRoomID .. ")", "Route", "Attempt to find a speedwalk to this location (" .. sQuowLocationsByRoomID[sBookmarkedRoomID][1] .. "," .. sQuowLocationsByRoomID[sBookmarkedRoomID][2] .. "," .. sQuowLocationsByRoomID[sBookmarkedRoomID][3] .. ")", sGlobalColourOrange, "", 0)
if (sSearchPhrase == "") then
Tell(" | ")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowDeleteBookmark(" .. sBookmarkedRoomID .. ")", "Delete", "Delete this bookmark", sGlobalColourOrange, "", 0)
Tell(" | ")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowRenameBookmark(" .. sBookmarkedRoomID .. ")", "Rename", "Rename the room for this bookmark", sGlobalColourOrange, "", 0)
end
Tell("] ")
if (sSearchPhrase ~= "") then
Tell("(")
ColourTell(sGlobalColourCyan, sGlobalColourBlack, "bookmarked")
Tell(") ")
end
if (sBookmarkNote == "") then
Tell(sQuowLocationsByRoomID[sBookmarkedRoomID][4])
else
Tell(sBookmarkNote)
end
Tell(" (" .. sQuowMapfiles[sQuowLocationsByRoomID[sBookmarkedRoomID][1]][2] .. ")")
Note("")
end
end
return iBookmarkFinds
end
-- Rename a user location bookmark
function QuowRenameBookmark(sRenameThisBookmarkID)
sSQL = ""
if (sQuowUserBookmarks[sRenameThisBookmarkID] ~= nil) then
sPopupResult = utils.inputbox("Please type a replacement name for the room '" .. sQuowLocationsByRoomID[sRenameThisBookmarkID][4] .. "'.\n\nLeaving it blank will default to the original room name.", "Bookmark Rename", sQuowUserBookmarks[sRenameThisBookmarkID], "", 12 )
if (sPopupResult ~= nil) then
sSQL = "UPDATE bookmarks SET note='" .. EscapeSQL(sPopupResult) .. "' WHERE room_id='" .. sRenameThisBookmarkID .. "'"
assert(dbUserData:execute(sSQL))
--Reorder alphabetically
sSortedBookmarks = {}
for row in dbUserData:nrows("SELECT room_id, note FROM bookmarks") do
if (sQuowLocationsByRoomID[row.room_id] ~= nil) then
table.insert(sSortedBookmarks, {row.room_id, row.note})
end
end
table.sort(sSortedBookmarks, QuowBookmarkCompare)
sQuowUserBookmarks[sRenameThisBookmarkID] = sPopupResult
if (sPopupResult == "") then
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "The bookmarked room '")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, sQuowLocationsByRoomID[sRenameThisBookmarkID][4])
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "' name has been set to the original room name.")
else
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "The bookmarked room '")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, sQuowLocationsByRoomID[sRenameThisBookmarkID][4])
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "' has been renamed to '")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, sPopupResult)
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "'")
end
else
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "The bookmarked room '")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, sQuowLocationsByRoomID[sRenameThisBookmarkID][4])
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "' has not been renamed.")
end
end
end
-- Delete a user location bookmark
function QuowDeleteBookmark(sDeleteThisBookmarkID)
sSQL = ""
if (sQuowUserBookmarks[sDeleteThisBookmarkID] ~= nil) then
sSQL = "DELETE FROM bookmarks WHERE room_id='" .. sDeleteThisBookmarkID .. "'"
assert(dbUserData:execute(sSQL))
sQuowUserBookmarks[sDeleteThisBookmarkID] = nil
if (sQuowLocationsByRoomID[sDeleteThisBookmarkID] ~= nil) then
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "The bookmark for '")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, sQuowLocationsByRoomID[sDeleteThisBookmarkID][4])
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "' has been removed from your list.")
end
end
end
-- Create a user location bookmark
function QuowCreateBookmark(sCreateThisBookmarkID)
sSQL = ""
if (sQuowLocationsByRoomID[sCreateThisBookmarkID] ~= nil and sQuowUserBookmarks[sCreateThisBookmarkID] == nil) then
sQuowUserBookmarks[sCreateThisBookmarkID] = ''
sSQL = "INSERT INTO bookmarks VALUES ('" .. sCreateThisBookmarkID .. "', '')"
assert(dbUserData:execute(sSQL))
--Reorder alphabetically
sSortedBookmarks = {}
for row in dbUserData:nrows("SELECT room_id, note FROM bookmarks") do
if (sQuowLocationsByRoomID[row.room_id] ~= nil) then
table.insert(sSortedBookmarks, {row.room_id, row.note})
end
end
table.sort(sSortedBookmarks, QuowBookmarkCompare)
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "A new bookmark has been added for '")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowRenameBookmark(" .. sCreateThisBookmarkID .. ")", sQuowLocationsByRoomID[sCreateThisBookmarkID][4], "Rename the room for this bookmark", sGlobalColourOrange, "", 0)
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "' (")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowRenameBookmark(" .. sCreateThisBookmarkID .. ")", "click to rename", "Rename the room for this bookmark", sGlobalColourOrange, "", 0)
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "). Type 'minimap bookmarks' to view them.")
end
end
-- Display room-info in-client
function QuowShowRoomInfo(sDisplayThisRoomID)
if (sQuowLocationsByRoomID[sDisplayThisRoomID] ~= nil) then
Note("")
Tell("'")
ColourTell(sGlobalColourOrange, sGlobalColourBlack, sQuowLocationsByRoomID[sDisplayThisRoomID][4])
Note("'")
if (sQuowUserBookmarks[sDisplayThisRoomID] ~= nil and sQuowUserBookmarks[sDisplayThisRoomID] ~= "") then
Tell("Bookmarked as: '")
ColourTell(sGlobalColourCyan, sGlobalColourBlack, sQuowUserBookmarks[sDisplayThisRoomID])
Note("'")
end
Tell("Room Type: ")
ColourNote(iGlobalColourSilver, sGlobalColourBlack, sQuowLocationsByRoomID[sDisplayThisRoomID][5])
Tell("Map Region: ")
ColourNote(iGlobalColourSilver, sGlobalColourBlack, sQuowMapfiles[sQuowLocationsByRoomID[sDisplayThisRoomID][1]][2])
Tell("Share Command: '")
ColourTell(iGlobalColourSilver, sGlobalColourBlack, "minimap {" .. sQuowLocationsByRoomID[sDisplayThisRoomID][1] .. ", " .. sQuowLocationsByRoomID[sDisplayThisRoomID][2] .. ", " .. sQuowLocationsByRoomID[sDisplayThisRoomID][3] .. "}")
Note("'")
Tell("Recognised room exits: ")
local bDoComma = false
for sKey, sData in pairs(sQuowExitsByExit[sDisplayThisRoomID]) do
if (bDoComma == true) then
Tell(", ")
end
ColourTell(iGlobalColourSilver, sGlobalColourBlack, sKey)
bDoComma = true
end
if (bDoComma == false) then
Tell("(no known exits)")
end
Note("")
local iAnyFinds = 0
if (sQuowLocationsByRoomID[sDisplayThisRoomID][6] == 1) then
for sStockCode, sStocklist in pairs(sQuowShopItems[sDisplayThisRoomID]) do
iAnyFinds = iAnyFinds + 1
ColourNote(iGlobalColourSilver, sGlobalColourBlack, " " .. sStockCode .. ": " .. sStocklist[1] .. " @ " .. sStocklist[2])
end
end
if (iAnyFinds == 0) then
ColourNote(iGlobalColourSilver, sGlobalColourBlack, "No recorded shop inventory.")
end
Note("--- End of room info ---")
else
Note("Unable to display room data. Click on a valid room first, and that the map 'snaps' to it on clicking.")
end
end
-- Snap map back to "old" co-ordinates
function QuowOldSnap()
-- Snap back to "old" co-ordinates
iMyX = iOldMX
iMyY = iOldMY
iCurMap = iOldMap
sCurrentMap = sOldMap
RedrawMap()
Repaint()
end
-- ********************************************************************
-- ***** Redraw the visible graphical map window and all contents *****
-- ********************************************************************
function RedrawMap()
-- Save effort, do nothing if not showing this window
if (WINDATA[winMinimap]["SHOW"] == false or bMinimapHidden == true) then
return
end
-- Handle any queue map-shift?
local iShiftX = 0
local iShiftY = 0
local iUseMap = iCurMap
for iKey, sShiftData in ipairs(iMapShiftQueue) do
iShiftX = iShiftX + sShiftData[1]
iShiftY = iShiftY + sShiftData[2]
iUseMap = sShiftData[4]
end
--if (bDrawSkeletonMode == false) then bDrawSkeletonMode = true else bDrawSkeletonMode = false end
--Note("Debug: Re-drawing map: " .. iCurMap .. ", " .. iMyX .. " / " .. iMyY .. " ... shifts=" .. #iMapShiftQueue .. " to " .. iShiftX .. " / " .. iShiftY)
if (iUseMap == 0 or sQuowMapfiles[iUseMap] == nil) then
-- Clear the map window all black
WindowRectOp (winMinimap, 2, 0, winThemeData.TITLE_HEIGHT, MINIMAP_WIDTH, WINDATA[winMinimap]["HEIGHT"], iGlobalColourWhite)
-- Draw a border so we can see the window clearly when a map graphic isn't being displayed
WindowRectOp(winMinimap, miniwin.rect_frame, 0, winThemeData.TITLE_HEIGHT, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], iGlobalColourSilver, iGlobalColourWhite)
-- Update Disc game date if needed
if (bShowDiscDate == true) then
DrawDiscDate(false)
end
-- Change brightness of the maps window
if (iMinimapBrightness < 100) then
WindowFilter (winMinimap, 0, winThemeData.TITLE_HEIGHT, MINIMAP_WIDTH, WINDATA[winMinimap]["HEIGHT"], 21, (iMinimapBrightness / 100)) -- halve the brightness
end
WindowText (winMinimap, "bodyfont"..winMinimap, "(unknown location)", 2, winThemeData.TITLE_HEIGHT + 2, 0, 0, iGlobalColourSilver)
-- And quit this function now since we don't even know where we are!
return
end
-- Get the file-path of this map we're on
sCurrentMap = sQuowMapfiles[iUseMap][1]
local iDrawX = math.floor((iMyX + iShiftX) - MINIMAP_CX)
local iDrawY = math.floor((iMyY + iShiftY) - MINIMAP_CY)
-- Bounds limit
local iMaxX = iDrawX + MINIMAP_WIDTH
local iMaxY = iDrawY + WINDATA[winMinimap]["HEIGHT"]
-- handle map file changes
if (sLoadedMap ~= sCurrentMap) then
WindowLoadImage (winMinimap, "QuowImg", sQuowMapPath .. sCurrentMap)
sLoadedMap = sCurrentMap
RetitleWindow(winMinimap, sQuowMapfiles[iUseMap][2])
end
if (sLoadedMap ~= "") then
WindowRectOp (winMinimap, 2, 0, winThemeData.TITLE_HEIGHT, MINIMAP_WIDTH, WINDATA[winMinimap]["HEIGHT"], 16777215)
if (bDrawSkeletonMode == false or iCurMap == 47 or iCurMap == 8) then
WindowDrawImage (winMinimap, "QuowImg", MINIMAP_X, MINIMAP_Y, MINIMAP_WIDTH, MINIMAP_HEIGHT, 1, iDrawX, iDrawY + winThemeData.TITLE_HEIGHT, iDrawX + MINIMAP_WIDTH, (iDrawY + MINIMAP_HEIGHT) + winThemeData.TITLE_HEIGHT)
end
-- Draw all known rooms found rooms mapped rooms on the map
if (bCreatingRooms == true or bDrawSkeletonMode == true) then
local iTX = 0
local iTY = 0
local iRoomColour = 42495
for sKey, sRoomID in pairs(sQuowLocationsByRoomID) do
if (sRoomID[1] == iUseMap) then
if (sRoomID[2] >= iDrawX and sRoomID[2] <= iMaxX and sRoomID[3] >= (iDrawY + winThemeData.TITLE_HEIGHT) and sRoomID[3] <= iMaxY) then
iTX = sRoomID[2] - iDrawX
iTY = sRoomID[3] - iDrawY
-- Draw exits?
if (bDrawSkeletonMode == true) then
for sExit, sData in pairs(sQuowExitsByExit[sKey]) do
if (sQuowLocationsByRoomID[sData][1] == iUseMap and sQuowLocationsByRoomID[sData][2] >= iDrawX and sQuowLocationsByRoomID[sData][2] <= iMaxX and sQuowLocationsByRoomID[sData][3] >= (iDrawY + winThemeData.TITLE_HEIGHT) and sQuowLocationsByRoomID[sData][3] <= iMaxY) then
WindowLine (winMinimap, iTX, iTY, sQuowLocationsByRoomID[sData][2] - iDrawX, sQuowLocationsByRoomID[sData][3] - iDrawY, 16711680, 0, 1)
end
end -- Loop through exits
-- Draw room - shop, else indoor/outdoor
if (sQuowLocationsByRoomID[sKey][6] == 1) then
iRoomColour = 16748574
else
-- Draw room
if (sQuowLocationsByRoomID[sKey][5] == "outside") then
iRoomColour = 42495
else
iRoomColour = 16711935
end
end
WindowRectOp (winMinimap, 2, iTX-2, iTY-2, iTX+4, iTY+4, iRoomColour)
else
-- Draw smaller room
WindowRectOp (winMinimap, 2, iTX-1, iTY-1, iTX+3, iTY+3, 42495)
end
end
end
end
end
if (iUseMap == 47) then
-- UU Library draw directional arrow
if (sLastDir == "n" or sLastDir == "north") then
WindowLine (winMinimap, MINIMAP_CX - 7, MINIMAP_CY, MINIMAP_CX, MINIMAP_CY - 7, 16711680, 0, 5)
WindowLine (winMinimap, MINIMAP_CX + 7, MINIMAP_CY, MINIMAP_CX, MINIMAP_CY - 7, 16711680, 0, 5)
elseif (sLastDir == "e" or sLastDir == "east") then
WindowLine (winMinimap, MINIMAP_CX, MINIMAP_CY - 7, MINIMAP_CX + 7, MINIMAP_CY, 16711680, 0, 5)
WindowLine (winMinimap, MINIMAP_CX, MINIMAP_CY + 7, MINIMAP_CX + 7, MINIMAP_CY, 16711680, 0, 5)
elseif (sLastDir == "s" or sLastDir == "south") then
WindowLine (winMinimap, MINIMAP_CX - 7, MINIMAP_CY, MINIMAP_CX, MINIMAP_CY + 7, 16711680, 0, 5)
WindowLine (winMinimap, MINIMAP_CX + 7, MINIMAP_CY, MINIMAP_CX, MINIMAP_CY + 7, 16711680, 0, 5)
elseif (sLastDir == "w" or sLastDir == "west") then
WindowLine (winMinimap, MINIMAP_CX, MINIMAP_CY - 7, MINIMAP_CX - 7, MINIMAP_CY, 16711680, 0, 5)
WindowLine (winMinimap, MINIMAP_CX, MINIMAP_CY + 7, MINIMAP_CX - 7, MINIMAP_CY, 16711680, 0, 5)
end
end
-- Current map centre and ghost
if (bDrawSkeletonMode == true and iCurMap ~= 47 and iCurMap ~= 8) then
-- larger for skeleton mode
-- Ghost
if (iCharLocMap == iCurMap and (bShowGhost == true or iCurMap == 47 or iCurMap == 8) and iCatchupX >= iDrawX and iCatchupX <= iMaxX and iCatchupY >= (iDrawY + winThemeData.TITLE_HEIGHT) and iCatchupY <= iMaxY) then
WindowRectOp (winMinimap, 2, (iCatchupX - iDrawX)-3, (iCatchupY - iDrawY)-3, (iCatchupX - iDrawX)+5, (iCatchupY - iDrawY)+5, 255)
end
-- Centre
WindowRectOp (winMinimap, 2, MINIMAP_CX-3, MINIMAP_CY-3, MINIMAP_CX+5, MINIMAP_CY+5, 0)
else
-- Ghost
if (iCharLocMap == iCurMap and (bShowGhost == true or iCurMap == 47 or iCurMap == 8) and iCatchupX >= iDrawX and iCatchupX <= iMaxX and iCatchupY >= (iDrawY + winThemeData.TITLE_HEIGHT) and iCatchupY <= iMaxY) then
WindowRectOp (winMinimap, 2, (iCatchupX - iDrawX)-2, (iCatchupY - iDrawY)-2, (iCatchupX - iDrawX)+4, (iCatchupY - iDrawY)+4, 42495)
end
WindowRectOp (winMinimap, 2, MINIMAP_CX-2, MINIMAP_CY-2, MINIMAP_CX+4, MINIMAP_CY+4, 255)
end
end
-- Update Disc game date if needed
if (bShowDiscDate == true) then
DrawDiscDate(false)
end
-- Change brightness of the maps window
if (iMinimapBrightness < 100) then
WindowFilter (winMinimap, 0, winThemeData.TITLE_HEIGHT, MINIMAP_WIDTH, WINDATA[winMinimap]["HEIGHT"], 21, (iMinimapBrightness / 100)) -- halve the brightness
end
end
-- *******************************************************
-- ***** Handle Score-Brief and Combat Monitor lines *****
-- *******************************************************
function QuowHandleScoreBrief(sName, sLine, wildcards, styles)
local iMaxHP = tonumber(wildcards[2])
local iMaxGP = tonumber(wildcards[4])
-- Try to avoid fakes
if ((iMaxHP ~= -1 and iMaxHP ~= iCharVitals["maxhp"]) or (iMaxGP ~= -1 and iMaxGP ~= iCharVitals["maxgp"])) then
return
end
OnPluginMXPsetEntity("hp="..wildcards[1], true)
OnPluginMXPsetEntity("gp="..wildcards[3], true)
OnPluginMXPsetEntity("xp="..wildcards[5], true)
if (wildcards[6] ~= "") then
OnPluginMXPsetEntity ("burden=" .. wildcards[6], true)
else
-- This a combat monitor line - Add up the combat stats
iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] = iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] + 1
RedrawStatsWindow()
end
RedrawVitalsWindow()
RedrawXPWindow()
Repaint()
end
-- ********************************************************
-- ***** Handle MXP background Data sent by Discworld *****
-- ********************************************************
local sNoticeText = ""
function OnPluginMXPsetEntity (sIn, bDelayUpdates)
local sValue = utils.split(sIn, '=')
-- Is this a stat we care about?
if (iCharVitals[sValue[1]] ~= nil) then
iCharOldVitals[sValue[1]] = iCharVitals[sValue[1]]
iCharVitals[sValue[1]] = tonumber(sValue[2])
-- First XP update?
if (sValue[1] == "xp") then
if (iXPTotalMinutePrevious == nil and (iCharVitals["maxhp"] > 0 or iCharVitals["maxgp"] > 0)) then
iXPTotalMinutePrevious = iCharVitals["xp"]
iXPTotalMinuteCurrent = iCharVitals["xp"]
end
if (bShowXPNotifications == true) then
local iXPDiff = iCharVitals["xp"] - iCharOldVitals["xp"]
if (iXPDiff > 1000) then
sNoticeText = "+" .. tostring(iXPDiff) .. " XP"
if (string.len(sNoticeText) > 0) then
table.insert(sTextNoticesQueue, {2, sNoticeText, 1})
AddTimer("NotificationTimer", 0, 0, 0.1, "", 17445, "QuowDisplayNotices")
end
end
end
elseif (bShowHPNotifications == true and sValue[1] == "hp") then
local iHPDiff = iCharVitals["hp"] - iCharOldVitals["hp"]
if (iHPDiff < 0) then
sNoticeText = tostring(iHPDiff) .. " HP"
if (string.len(sNoticeText) > 0) then
table.insert(sTextNoticesQueue, {1, sNoticeText, 1})
AddTimer("NotificationTimer", 0, 0, 0.1, "", 17445, "QuowDisplayNotices")
end
end
end
if (bDelayUpdates == nil or bDelayUpdates == false) then
if (sValue[1] == "xp" or sValue[1] == "burden") then
RedrawVitalsWindow()
RedrawXPWindow()
Repaint()
end
end
end
end
-- *******************************************************
-- ***** Safety Check - See if we have GMCP enabled! *****
-- *******************************************************
iExitsFirstSeen = nil
iLastGivenWarning = 0
function QuowConfirmExitsSeen()
local iNow = os.time()
if (iExitsFirstSeen == nil) then
iExitsFirstSeen = iNow
else
if ((iNow - iExitsFirstSeen) > 20 and (iNow - iLastGivenWarning) > 600) then
iLastGivenWarning = iNow
Note("")
ColourNote("red", sGlobalColourBlack, "===== Quow's Cow Bar Warning: =====")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You do not seem to be receiving GMCP data from the Discworld!")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This means the map will not know where you are, and many core functions will not work at all, until you reconnect to the MUD.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "You do NOT need to log out of the mud or 'quit'! Simply go to the 'Connection' menu at the top of MUSHclient, and select Disconnect. Then Re-Connect and log back in!")
Note("(this warning will appear once every ten minutes until the problem is resolved)")
Note("")
end
end
end
-- *********************************************************
-- ***** Handle GMCP background Data sent by Discworld *****
-- *********************************************************
-- GMCP values
local IAC, SB, SE, DO = 0xFF, 0xFA, 0xF0, 0xFD
local GMCP = 201
bIgnoreBroadcasts = false
-- Actually send a GMCP packet to the MUD (has to be packaged up specially)
function Send_GMCP_Packet (sPacketData)
assert (sPacketData, "Send_GMCP_Packet passed a nil message.")
SendPkt (string.char (IAC, SB, GMCP) .. (string.gsub (sPacketData, "\255", "\255\255")) .. string.char (IAC, SE))
end -- Send_GMCP_Packet
-- Set up GMCP on connection start
function OnPluginTelnetRequest (msg_type, sDataLine)
if (msg_type == GMCP) then
if (sDataLine == "WILL") then
return true
elseif (sDataLine == "SENT_DO") then
-- Tell the MUD which GMCP elements we want to switch on - get them all so we can re-broadcast for other plugins
Send_GMCP_Packet (string.format ('Core.Hello { "client": "MUSHclient", "version": "%s" }', Version()))
-- Send_GMCP_Packet ('Core.Supports.Set [ "Char.Vitals", "Window.Frame.map" ]')
-- Char.Vitals = character basic data
-- Window.Frame.map = ascii map - being made redundant/changing to room.map
-- room.map = ascii map
-- room.writtenmap = MDT mapf
local sSupports = '"room.info"'
if (bRequestRoomMap == true) then
sSupports = sSupports .. ', "room.map"'
end
if (bRequestWrittenMap == true) then
sSupports = sSupports .. ', "room.writtenmap"'
end
if (bRequestCharVitals == true) then
sSupports = sSupports .. ', "Char.Vitals"'
end
--Note('Core.Supports.Set [ ' .. sSupports .. ' ]')
Send_GMCP_Packet ('Core.Supports.Set [ ' .. sSupports .. ' ]')
return true
end -- if GMCP login needed (just sent DO)
end
return false
end -- function OnPluginTelnetRequest
-- ***********************************
-- ***** Handle a GMCP data line *****
-- ***********************************
function QuowHandleGMCPLine(sThisGMCP)
-- Output debug GMCP debug data line
--Note("GMCP:" .. sThisGMCP)
-- Turn off the no-gmcp warnings
EnableTrigger("RoomExitsSeenLong", false)
EnableTrigger("RoomExitsSeenShort", false)
-- Handle the GMCP string type
if (string.sub(sThisGMCP, 1, 11) == "room.info {") then
-- Now for the GMCP stuff
local sDecodeStats = json.decode(string.sub(sThisGMCP, 11))
sPreviousRoomID = sCurrentRoomID
if (sDecodeStats["identifier"] ~= nil and sDecodeStats["name"] ~= nil and sDecodeStats["kind"] ~= nil) then
sCurrentRoomID = sDecodeStats["identifier"]
sThisRoomTitle = sDecodeStats["name"]
sThisRoomType = sDecodeStats["kind"]
bLSpaceDepths = false
else
sCurrentRoomID = "UnknownRoom"
sThisRoomTitle = "unknown location"
sThisRoomType = "unknown"
end
RoomIDMapFind()
elseif (string.sub(sThisGMCP, 1, 13) == "Char.Vitals {") then
if (MODULES["vitals"] == true) then
-- Char Vitals
for sVitalStat, iVitalData in pairs(iCharVitals) do
iCharOldVitals[sVitalStat] = iVitalData
end
iCharVitals = json.decode(string.sub(sThisGMCP, 13))
if (bShowXPNotifications == true) then
local iXPDiff = iCharVitals["xp"] - iCharOldVitals["xp"]
if (iXPDiff > 1000) then
sNoticeText = "+" .. tostring(iXPDiff) .. " XP"
if (string.len(sNoticeText) > 0) then
table.insert(sTextNoticesQueue, {2, sNoticeText, 2})
AddTimer("NotificationTimer", 0, 0, 0.1, "", 17445, "QuowDisplayNotices")
end
end
end
if (bShowHPNotifications == true) then
local iHPDiff = iCharVitals["hp"] - iCharOldVitals["hp"]
if (iHPDiff < 0) then
sNoticeText = tostring(iHPDiff) .. " HP"
if (string.len(sNoticeText) > 0) then
table.insert(sTextNoticesQueue, {1, sNoticeText, 2})
AddTimer("NotificationTimer", 0, 0, 0.1, "", 17445, "QuowDisplayNotices")
end
end
end
-- First XP update?
if (iXPTotalMinutePrevious == nil and (iCharVitals["maxhp"] ~= 0 or iCharVitals["maxgp"] ~= 0)) then
iXPTotalMinutePrevious = iCharVitals["xp"]
iXPTotalMinuteCurrent = iCharVitals["xp"]
end
RedrawVitalsWindow()
RedrawXPWindow()
Repaint()
end
elseif (string.sub(sThisGMCP, 1, 9) == "room.map ") then
-- Prepare the ascii map line table, if the module is enabled
if (MODULES["ascii"] == true) then
sASCIIMapLineStyles = {}
bAsciiSeenYellow = false
iASCIIWidth = 0
if (bAsciiFoundMatch == false and bAsciiShownWarning == false) then
bAsciiShownWarning = true
DoAfterSpecial (1, "QuowbarAsciiWarning()", sendto.script)
end
bAsciiFoundMatch = false
-- Ascii MAP
sThisGMCP = string.sub(sThisGMCP, 11, -2)
if (sThisGMCP == "") then
bAsciiFoundMatch = true
EnableTrigger("AsciiMapLine", false)
EnableTrigger("AsciiMapPre", false)
if (bAsciiMapOmitted == true) then
SetTriggerOption("AsciiMapLine", "omit_from_output", "n")
end
RedrawAsciiWindow()
else
sAsciiMapString, iAsciiMapLines = sThisGMCP:gsub("\\n", "\\n")
-- Grab the very first line of the ascii map
local iWhereAt = string.find(sAsciiMapString, "\\n")
if (iWhereAt > 0) then
sAsciiMapString = string.sub(sAsciiMapString, 1, iWhereAt - 1)
end
sAsciiMapString = string.gsub(sAsciiMapString, "\\u001b%[%w%w", "")
sAsciiMapString = string.gsub(sAsciiMapString, "MXP<.->", "")
sAsciiMapString = string.gsub(sAsciiMapString, "\\/", "/")
sAsciiMapString = string.gsub(sAsciiMapString, "\\\\", "\\")
if (bAsciiMapOmitted == true) then
SetTriggerOption("AsciiMapLine", "omit_from_output", "y")
else
SetTriggerOption("AsciiMapLine", "omit_from_output", "n")
end
EnableTrigger("AsciiMapPre", true)
end
end
elseif (string.sub(sThisGMCP, 1, 16) == "room.writtenmap " and WINDATA[winMDT]["SHOW"] == true) then
-- MDT map
if (MODULES["mdt"] == true) then
sLastFullMDT = ""
sThisGMCP = string.sub(sThisGMCP, 18, string.len(sThisGMCP) - 3)
iReturnCode, iMDTMinimumRoomValue, sJSONSquaresTable, sJSONEntityTable = CallPlugin ("bff25308e015986fb1a56e3e", "QuowHandleDoorTextFull", "RemoteRequest", sThisGMCP)
if (iReturnCode == 0 and sJSONSquaresTable ~= nil and sJSONSquaresTable ~= "" and sJSONEntityTable ~= nil and sJSONEntityTable ~= "") then
for sTKey, objEntity in pairs(iEnemiesBySquare) do
iEnemiesBySquare[sTKey] = nil
end
for sTKey, objEntity in pairs(objEntityTable) do
objEntityTable[sTKey] = nil
end
iEnemiesBySquare = json.decode(sJSONSquaresTable)
objEntityTable = json.decode(sJSONEntityTable)
table.sort(iEnemiesBySquare, QuowValueCompare)
iTotalMDTLines = 0
iLongestMDTDir = 0
iMDTRoomsIgnored = 0
-- Grab shortest
for iKey, sValue in pairs (iEnemiesBySquare) do
-- Only show if this room has at least "iMDTMinimumRoomValue" value
if (sValue[4] >= iMDTMinimumRoomValue) then
iTotalMDTLines = iTotalMDTLines + 1
if (string.len(sValue[2]) > iLongestMDTDir) then
iLongestMDTDir = string.len(sValue[2])
end
else
iMDTRoomsIgnored = iMDTRoomsIgnored + 1
end
end
if (iMDTRoomsIgnored > 0) then
iTotalMDTLines = iTotalMDTLines + 1
end
else
sLastFullMDT = sThisGMCP
end
RedrawMDTWindow()
end
end
end
-- ******************************************
-- ***** Primary GMCP Receiver from MUD *****
-- ******************************************
-- On plugin callback to pick up GMCP stuff
function OnPluginTelnetSubnegotiation (msg_type, sDataLine)
if (msg_type ~= GMCP) then
return
end -- if not GMCP
-- GMCP Line handler
QuowHandleGMCPLine(sDataLine)
-- Re-package, re-broadcast, for other plugins to receive GMCP data
message, params = string.match (sDataLine, "([%a.]+)%s+(.*)")
-- if valid format, broadcast to all interested plugins
if (message) then
BroadcastPlugin(1, sDataLine)
end
end
-- ******************************************************
-- ***** Broadcast GMCP Receiver from other plugins *****
-- ******************************************************
function OnPluginBroadcast(msg, id, name, sDataLine)
-- We ignore other broadcasts if we've already detected our own GMCP, so we don't double-up
if (bIgnoreBroadcasts == false) then
QuowHandleGMCPLine(sDataLine)
end
end
-- ****************************************
-- ***** Quick Table Sorting Function *****
-- ****************************************
function QuowValueCompare(a, b)
return a[4] > b[4]
end
-- ****************************************************
-- ***** Set up all the shown/hidden combat texts *****
-- ****************************************************
function TriggersShowHide()
SetTriggerOption(tostring("QuowMeleeSpecialPrepare1"), "omit_from_output", sUSER_OPTIONS["omit_special_prep"])
SetTriggerOption(tostring("QuowMeleeSpecialPrepare2"), "omit_from_output", sUSER_OPTIONS["omit_special_prep"])
SetTriggerOption(tostring("QuowMeleeSpecialPrepare3"), "omit_from_output", sUSER_OPTIONS["omit_special_prep"])
-- You failing to prepare/do specials
SetTriggerOption(tostring("QuowMeleeSpecialFail1"), "omit_from_output", sUSER_OPTIONS["omit_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail2"), "omit_from_output", sUSER_OPTIONS["omit_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail3"), "omit_from_output", sUSER_OPTIONS["omit_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail4"), "omit_from_output", sUSER_OPTIONS["omit_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail5"), "omit_from_output", sUSER_OPTIONS["omit_special_fail"])
for iN = 1, 7 do
-- You special-hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCatSpecial" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_out_success"])
-- Enemy special-hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCatSpecial" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_inc_success"])
-- Third special-hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCatSpecial" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_third_success"])
-- You hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_out_success"])
-- Enemy hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_success"])
-- Third party hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_third_success"])
end
for iN = 1, 5 do
-- Enemy defending you special-hitting
SetTriggerOption(tostring("QuowMeleeFailOutCatSpecial" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_out_fail"])
-- You defending an enemy special-hitting
SetTriggerOption(tostring("QuowMeleeFailIncCatSpecial" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_inc_fail"])
-- Third party defending special-hitting
SetTriggerOption(tostring("StatsMeleeFailThirdCatSpecial" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
-- Enemy defending you
SetTriggerOption(tostring("QuowMeleeFailOutCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_out_fail"])
-- You defending an enemy
SetTriggerOption(tostring("QuowMeleeFailIncCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_fail"])
-- Third party defending
SetTriggerOption(tostring("StatsMeleeFailThirdCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_third_fail"])
end
for iN = 1, 3 do
-- Enemy defends your special
SetTriggerOption(tostring("QuowSpecialFailOutCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_out_fail"])
-- Your special hits
SetTriggerOption(tostring("QuowSpecialSuccessOutCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_out_success"])
-- You defend an enemy special
SetTriggerOption(tostring("QuowSpecialFailIncCat" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_inc_fail"])
-- Enemy hits you with a special
SetTriggerOption(tostring("QuowSpecialSuccessIncCat" .. iN), "omit_from_output", sUSER_OPTIONS["col_special_inc_success"])
-- Third party defends special
SetTriggerOption(tostring("StatsSpecialFailThird" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
-- Third party hits special
SetTriggerOption(tostring("StatsSpecialSuccessThird" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_third_success"])
end
for iN = 1, iCustomCombatLinesFailNormal do
if (IsTrigger("StatsMeleeFailThirdCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_out_fail"])
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_fail"])
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_third_fail"])
end
end
for iN = 1, iCustomCombatLinesNormal do
if (IsTrigger("QuowMeleeSuccessOutCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessOutCat_Custom" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_out_success"])
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessIncCat_Custom" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_success"])
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat_Custom" .. iN), "omit_from_output", sUSER_OPTIONS["omit_melee_third_success"])
end
end
for iN = 1, iCustomCombatLinesSpecial do
if (IsTrigger("QuowSpecialSuccessOutS" .. iN) == 0) then
-- You pull off a big unique special
SetTriggerOption(tostring("QuowSpecialSuccessOutS" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_out_success"])
end
if (IsTrigger("QuowSpecialSuccessIncS" .. iN) == 0) then
-- Enemy pulls off a big unique special on you
SetTriggerOption(tostring("QuowSpecialSuccessIncS" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_inc_success"])
end
if (IsTrigger("StatsSpecialSuccessThirdS" .. iN) == 0) then
-- Third party does some big unique special
SetTriggerOption(tostring("StatsSpecialSuccessThirdS" .. iN), "omit_from_output", sUSER_OPTIONS["omit_special_third_success"])
end
end
-- You get a kill
SetTriggerOption(tostring("QuowKillStatOut1"), "omit_from_output", sUSER_OPTIONS["omit_melee_out_kill"])
-- Enemy kills you
SetTriggerOption(tostring("QuowKillStatInc1"), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_kill"])
-- Third party kills
SetTriggerOption(tostring("StatsKillStatThird1"), "omit_from_output", sUSER_OPTIONS["omit_melee_third_kill"])
-- You defend against some unique special
SetTriggerOption(tostring("QuowSpecialFailIncCustom1"), "omit_from_output", sUSER_OPTIONS["omit_special_inc_fail"])
-- You defend against some unique special
SetTriggerOption(tostring("QuowMiscFailInc1"), "omit_from_output", sUSER_OPTIONS["omit_special_inc_fail"])
-- You defend against a thrown weapon
SetTriggerOption(tostring("QuowThrowingFailInc1"), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_fail"])
SetTriggerOption(tostring("QuowThrowingFailInc2"), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_fail"])
SetTriggerOption(tostring("QuowThrowingFailInc3"), "omit_from_output", sUSER_OPTIONS["omit_melee_inc_fail"])
-- Third party fails to prepare a special on someone
SetTriggerOption(tostring("StatsSpecialFailThirdCustom1"), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
SetTriggerOption(tostring("StatsSpecialFailThirdCustom2"), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
-- Third party defends against third parties thrown weapon
SetTriggerOption(tostring("QuowThrowingFailThird1"), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
SetTriggerOption(tostring("QuowThrowingFailThird2"), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
SetTriggerOption(tostring("QuowThrowingFailThird3"), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
-- Ambushes, Absconds, and Backstabs
SetTriggerOption(tostring("QuowSpecialBackstabSuccessOut"), "omit_from_output", sUSER_OPTIONS["omit_special_out_success"])
SetTriggerOption(tostring("QuowSpecialAmbushSuccessOut"), "omit_from_output", sUSER_OPTIONS["omit_special_out_success"])
SetTriggerOption(tostring("QuowSpecialAbscondSuccessOut"), "omit_from_output", sUSER_OPTIONS["omit_special_out_success"])
SetTriggerOption(tostring("QuowSpecialAmbushFailOut"), "omit_from_output", sUSER_OPTIONS["omit_special_out_fail"])
SetTriggerOption(tostring("QuowSpecialBackstabSuccessInc"), "omit_from_output", sUSER_OPTIONS["omit_special_inc_success"])
SetTriggerOption(tostring("QuowSpecialBackstabFailInc"), "omit_from_output", sUSER_OPTIONS["omit_special_inc_fail"])
SetTriggerOption(tostring("QuowSpecialBackstabFail2Inc"), "omit_from_output", sUSER_OPTIONS["omit_special_inc_fail"])
SetTriggerOption(tostring("QuowSpecialBackstabSuccessThird"), "omit_from_output", sUSER_OPTIONS["omit_special_third_success"])
SetTriggerOption(tostring("QuowSpecialAmbushSuccessThird"), "omit_from_output", sUSER_OPTIONS["omit_special_third_success"])
SetTriggerOption(tostring("QuowSpecialAmbushFailThird"), "omit_from_output", sUSER_OPTIONS["omit_special_third_fail"])
SetTriggerOption(tostring("QuowSpecialAbscondSuccessThird"), "omit_from_output", sUSER_OPTIONS["omit_special_third_success"])
-- Feints
SetTriggerOption(tostring("QuowFeintSuccessIncoming1"), "omit_from_output", sUSER_OPTIONS["omit_special_inc_success"])
SetTriggerOption(tostring("QuowFeintFailIncoming1"), "omit_from_output", sUSER_OPTIONS["omit_special_inc_fail"])
SetTriggerOption(tostring("QuowFeintFailOutgoing1"), "omit_from_output", sUSER_OPTIONS["omit_special_out_fail"])
end
-- ****************************
-- ***** ASCII map errors *****
-- ****************************
function QuowbarAsciiWarning()
Note("")
ColourNote("red", "black", "Quow's Cow Bar Notice:")
ColourNote("darkorange", "black", "Unable to detect the ASCII map from the MUD... ")
ColourNote("silver", "black", "If your ASCII map window continues not to work repeatedly, things you can try are:")
ColourNote("darkorange", "black", "Your 'term' might need resetting, or 'options output map' settings need changing to 'top'")
ColourTell("darkorange", "black", "You should also consider doing '")
Hyperlink ("options output shortinlong=on", "options output shortinlong=on", "", sGlobalColourCyan, "", 0)
ColourTell("darkorange", "black", "' and '")
Hyperlink ("prompt off", "prompt off", "", sGlobalColourCyan, "", 0)
ColourNote("darkorange", "black", "' to help the plugin process game text more easily.")
ColourNote("silver", "black", "These things and more can be set by typing 'minimap discworldconfig' which changes many Disc-side settings for you.")
--ColourTell("darkorange", "black", "First though, try to ")
--Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowSetTerminal()", "fix your terminal type by clicking here", "", sGlobalColourCyan, "", 0)
--ColourNote("darkorange", "black", ".")
Note("")
end
-- ******************************
-- ***** Terminal Resetting *****
-- ******************************
function QuowSetTerminal()
Send("term ansi")
Send("term network")
Note("Attempting to reset your 'term' type connection to Discworld back to 'network'.")
end
-- ********************************************
-- ***** Prevent colouring of these lines *****
-- ********************************************
function TriggersNoColour()
if (MODULES["stats"] == true) then
SetTriggerOption(tostring("QuowMeleeSpecialPrepare1"), "custom_colour", sUSER_OPTIONS["nocol_special_prep"])
SetTriggerOption(tostring("QuowMeleeSpecialPrepare2"), "custom_colour", sUSER_OPTIONS["nocol_special_prep"])
SetTriggerOption(tostring("QuowMeleeSpecialPrepare3"), "custom_colour", sUSER_OPTIONS["nocol_special_prep"])
-- You failing to prepare/do specials
SetTriggerOption(tostring("QuowMeleeSpecialFail1"), "custom_colour", sUSER_OPTIONS["nocol_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail2"), "custom_colour", sUSER_OPTIONS["nocol_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail3"), "custom_colour", sUSER_OPTIONS["nocol_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail4"), "custom_colour", sUSER_OPTIONS["nocol_special_fail"])
SetTriggerOption(tostring("QuowMeleeSpecialFail5"), "custom_colour", sUSER_OPTIONS["nocol_special_fail"])
for iN = 1, 7 do
-- You special-hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCatSpecial" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_out_success"])
-- Enemy special-hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCatSpecial" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_inc_success"])
-- Third special-hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCatSpecial" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_third_success"])
-- You hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_out_success"])
-- Enemy hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_success"])
-- Third party hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_third_success"])
end
for iN = 1, 5 do
-- Enemy defending you special-hitting
SetTriggerOption(tostring("QuowMeleeFailOutCatSpecial" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_out_fail"])
-- You defending an enemy special-hitting
SetTriggerOption(tostring("QuowMeleeFailIncCatSpecial" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_inc_fail"])
-- Third party defending special-hitting
SetTriggerOption(tostring("StatsMeleeFailThirdCatSpecial" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
-- Enemy defending you
SetTriggerOption(tostring("QuowMeleeFailOutCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_out_fail"])
-- You defending an enemy
SetTriggerOption(tostring("QuowMeleeFailIncCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_fail"])
-- Third party defending
SetTriggerOption(tostring("StatsMeleeFailThirdCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_third_fail"])
end
for iN = 1, 3 do
-- Enemy defends your special
SetTriggerOption(tostring("QuowSpecialFailOutCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_out_fail"])
-- Your special hits
SetTriggerOption(tostring("QuowSpecialSuccessOutCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_out_success"])
-- You defend an enemy special
SetTriggerOption(tostring("QuowSpecialFailIncCat" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_inc_fail"])
-- Enemy hits you with a special
SetTriggerOption(tostring("QuowSpecialSuccessIncCat" .. iN), "custom_colour", sUSER_OPTIONS["col_special_inc_success"])
-- Third party defends special
SetTriggerOption(tostring("StatsSpecialFailThird" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
-- Third party hits special
SetTriggerOption(tostring("StatsSpecialSuccessThird" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_third_success"])
end
for iN = 1, iCustomCombatLinesFailNormal do
if (IsTrigger("StatsMeleeFailThirdCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_out_fail"])
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_fail"])
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_third_fail"])
end
end
for iN = 1, iCustomCombatLinesNormal do
if (IsTrigger("QuowMeleeSuccessOutCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessOutCat_Custom" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_out_success"])
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessIncCat_Custom" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_success"])
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat_Custom" .. iN), "custom_colour", sUSER_OPTIONS["nocol_melee_third_success"])
end
end
for iN = 1, iCustomCombatLinesSpecial do
if (IsTrigger("QuowSpecialSuccessOutS" .. iN) == 0) then
-- You pull off a big unique special
SetTriggerOption(tostring("QuowSpecialSuccessOutS" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_out_success"])
end
if (IsTrigger("QuowSpecialSuccessIncS" .. iN) == 0) then
-- Enemy pulls off a big unique special on you
SetTriggerOption(tostring("QuowSpecialSuccessIncS" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_inc_success"])
end
if (IsTrigger("StatsSpecialSuccessThirdS" .. iN) == 0) then
-- Third party does some big unique special
SetTriggerOption(tostring("StatsSpecialSuccessThirdS" .. iN), "custom_colour", sUSER_OPTIONS["nocol_special_third_success"])
end
end
-- You get a kill
SetTriggerOption(tostring("QuowKillStatOut1"), "custom_colour", sUSER_OPTIONS["nocol_melee_out_kill"])
-- Enemy kills you
SetTriggerOption(tostring("QuowKillStatInc1"), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_kill"])
-- Third party kills
SetTriggerOption(tostring("StatsKillStatThird1"), "custom_colour", sUSER_OPTIONS["nocol_melee_third_kill"])
-- You defend against some unique special
SetTriggerOption(tostring("QuowSpecialFailIncCustom1"), "custom_colour", sUSER_OPTIONS["nocol_special_inc_fail"])
-- You defend against some unique special
SetTriggerOption(tostring("QuowMiscFailInc1"), "custom_colour", sUSER_OPTIONS["nocol_special_inc_fail"])
-- You defend against a thrown weapon
SetTriggerOption(tostring("QuowThrowingFailInc1"), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_fail"])
SetTriggerOption(tostring("QuowThrowingFailInc2"), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_fail"])
SetTriggerOption(tostring("QuowThrowingFailInc3"), "custom_colour", sUSER_OPTIONS["nocol_melee_inc_fail"])
-- Third party fails to prepare a special on someone
SetTriggerOption(tostring("StatsSpecialFailThirdCustom1"), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
SetTriggerOption(tostring("StatsSpecialFailThirdCustom2"), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
-- Third party defends against third parties thrown weapon
SetTriggerOption(tostring("QuowThrowingFailThird1"), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
SetTriggerOption(tostring("QuowThrowingFailThird2"), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
SetTriggerOption(tostring("QuowThrowingFailThird3"), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
-- Ambushes, Absconds, and Backstabs
SetTriggerOption(tostring("QuowSpecialBackstabSuccessOut"), "custom_colour", sUSER_OPTIONS["nocol_special_out_success"])
SetTriggerOption(tostring("QuowSpecialAmbushSuccessOut"), "custom_colour", sUSER_OPTIONS["nocol_special_out_success"])
SetTriggerOption(tostring("QuowSpecialAbscondSuccessOut"), "custom_colour", sUSER_OPTIONS["nocol_special_out_success"])
SetTriggerOption(tostring("QuowSpecialAmbushFailOut"), "custom_colour", sUSER_OPTIONS["nocol_special_out_fail"])
SetTriggerOption(tostring("QuowSpecialBackstabSuccessInc"), "custom_colour", sUSER_OPTIONS["nocol_special_inc_success"])
SetTriggerOption(tostring("QuowSpecialBackstabFailInc"), "custom_colour", sUSER_OPTIONS["nocol_special_inc_fail"])
SetTriggerOption(tostring("QuowSpecialBackstabFail2Inc"), "custom_colour", sUSER_OPTIONS["nocol_special_inc_fail"])
SetTriggerOption(tostring("QuowSpecialBackstabSuccessThird"), "custom_colour", sUSER_OPTIONS["nocol_special_third_success"])
SetTriggerOption(tostring("QuowSpecialAmbushSuccessThird"), "custom_colour", sUSER_OPTIONS["nocol_special_third_success"])
SetTriggerOption(tostring("QuowSpecialAmbushFailThird"), "custom_colour", sUSER_OPTIONS["nocol_special_third_fail"])
SetTriggerOption(tostring("QuowSpecialAbscondSuccessThird"), "custom_colour", sUSER_OPTIONS["nocol_special_third_success"])
-- Feints
SetTriggerOption(tostring("QuowFeintSuccessIncoming1"), "custom_colour", sUSER_OPTIONS["nocol_special_inc_success"])
SetTriggerOption(tostring("QuowFeintFailIncoming1"), "custom_colour", sUSER_OPTIONS["nocol_special_inc_fail"])
SetTriggerOption(tostring("QuowFeintFailOutgoing1"), "custom_colour", sUSER_OPTIONS["nocol_special_out_fail"])
else
SetTriggerOption(tostring("QuowMeleeSpecialPrepare1"), "custom_colour", "0")
SetTriggerOption(tostring("QuowMeleeSpecialPrepare2"), "custom_colour", "0")
SetTriggerOption(tostring("QuowMeleeSpecialPrepare3"), "custom_colour", "0")
-- You failing to prepare/do specials
SetTriggerOption(tostring("QuowMeleeSpecialFail1"), "custom_colour", "0")
SetTriggerOption(tostring("QuowMeleeSpecialFail2"), "custom_colour", "0")
SetTriggerOption(tostring("QuowMeleeSpecialFail3"), "custom_colour", "0")
SetTriggerOption(tostring("QuowMeleeSpecialFail4"), "custom_colour", "0")
SetTriggerOption(tostring("QuowMeleeSpecialFail5"), "custom_colour", "0")
for iN = 1, 7 do
-- You special-hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCatSpecial" .. iN), "custom_colour", "0")
-- Enemy special-hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCatSpecial" .. iN), "custom_colour", "0")
-- Third special-hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCatSpecial" .. iN), "custom_colour", "0")
-- You hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCat" .. iN), "custom_colour", "0")
-- Enemy hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCat" .. iN), "custom_colour", "0")
-- Third party hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat" .. iN), "custom_colour", "0")
end
for iN = 1, 5 do
-- Enemy defending you special-hitting
SetTriggerOption(tostring("QuowMeleeFailOutCatSpecial" .. iN), "custom_colour", "0")
-- You defending an enemy special-hitting
SetTriggerOption(tostring("QuowMeleeFailIncCatSpecial" .. iN), "custom_colour", "0")
-- Third party defending special-hitting
SetTriggerOption(tostring("StatsMeleeFailThirdCatSpecial" .. iN), "custom_colour", "0")
-- Enemy defending you
SetTriggerOption(tostring("QuowMeleeFailOutCat" .. iN), "custom_colour", "0")
-- You defending an enemy
SetTriggerOption(tostring("QuowMeleeFailIncCat" .. iN), "custom_colour", "0")
-- Third party defending
SetTriggerOption(tostring("StatsMeleeFailThirdCat" .. iN), "custom_colour", "0")
end
for iN = 1, 3 do
-- Enemy defends your special
SetTriggerOption(tostring("QuowSpecialFailOutCat" .. iN), "custom_colour", "0")
-- Your special hits
SetTriggerOption(tostring("QuowSpecialSuccessOutCat" .. iN), "custom_colour", "0")
-- You defend an enemy special
SetTriggerOption(tostring("QuowSpecialFailIncCat" .. iN), "custom_colour", "0")
-- Enemy hits you with a special
SetTriggerOption(tostring("QuowSpecialSuccessIncCat" .. iN), "custom_colour", "0")
-- Third party defends special
SetTriggerOption(tostring("StatsSpecialFailThird" .. iN), "custom_colour", "0")
-- Third party hits special
SetTriggerOption(tostring("StatsSpecialSuccessThird" .. iN), "custom_colour", "0")
end
for iN = 1, iCustomCombatLinesFailNormal do
if (IsTrigger("StatsMeleeFailThirdCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "custom_colour", "0")
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "custom_colour", "0")
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "custom_colour", "0")
end
end
for iN = 1, iCustomCombatLinesNormal do
if (IsTrigger("QuowMeleeSuccessOutCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessOutCat_Custom" .. iN), "custom_colour", "0")
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessIncCat_Custom" .. iN), "custom_colour", "0")
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat_Custom" .. iN), "custom_colour", "0")
end
end
for iN = 1, iCustomCombatLinesSpecial do
if (IsTrigger("QuowSpecialSuccessOutS" .. iN) == 0) then
-- You pull off a big unique special
SetTriggerOption(tostring("QuowSpecialSuccessOutS" .. iN), "custom_colour", "0")
end
if (IsTrigger("QuowSpecialSuccessIncS" .. iN) == 0) then
-- Enemy pulls off a big unique special on you
SetTriggerOption(tostring("QuowSpecialSuccessIncS" .. iN), "custom_colour", "0")
end
if (IsTrigger("StatsSpecialSuccessThirdS" .. iN) == 0) then
-- Third party does some big unique special
SetTriggerOption(tostring("StatsSpecialSuccessThirdS" .. iN), "custom_colour", "0")
end
end
-- You get a kill
SetTriggerOption(tostring("QuowKillStatOut1"), "custom_colour", "0")
-- Enemy kills you
SetTriggerOption(tostring("QuowKillStatInc1"), "custom_colour", "0")
-- Third party kills
SetTriggerOption(tostring("StatsKillStatThird1"), "custom_colour", "0")
-- You defend against some unique special
SetTriggerOption(tostring("QuowSpecialFailIncCustom1"), "custom_colour", "0")
-- You defend against some unique special
SetTriggerOption(tostring("QuowMiscFailInc1"), "custom_colour", "0")
-- You defend against a thrown weapon
SetTriggerOption(tostring("QuowThrowingFailInc1"), "custom_colour", "0")
SetTriggerOption(tostring("QuowThrowingFailInc2"), "custom_colour", "0")
SetTriggerOption(tostring("QuowThrowingFailInc3"), "custom_colour", "0")
-- Third party fails to prepare a special on someone
SetTriggerOption(tostring("StatsSpecialFailThirdCustom1"), "custom_colour", "0")
SetTriggerOption(tostring("StatsSpecialFailThirdCustom2"), "custom_colour", "0")
-- Third party defends against third parties thrown weapon
SetTriggerOption(tostring("QuowThrowingFailThird1"), "custom_colour", "0")
SetTriggerOption(tostring("QuowThrowingFailThird2"), "custom_colour", "0")
SetTriggerOption(tostring("QuowThrowingFailThird3"), "custom_colour", "0")
-- Ambushes, Absconds, and Backstabs
SetTriggerOption(tostring("QuowSpecialBackstabSuccessOut"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialAmbushSuccessOut"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialAbscondSuccessOut"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialAmbushFailOut"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialBackstabSuccessInc"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialBackstabFailInc"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialBackstabFail2Inc"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialBackstabSuccessThird"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialAmbushSuccessThird"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialAmbushFailThird"), "custom_colour", "0")
SetTriggerOption(tostring("QuowSpecialAbscondSuccessThird"), "custom_colour", "0")
-- Feints
SetTriggerOption(tostring("QuowFeintSuccessIncoming1"), "custom_colour", "0")
SetTriggerOption(tostring("QuowFeintFailIncoming1"), "custom_colour", "0")
SetTriggerOption(tostring("QuowFeintFailOutgoing1"), "custom_colour", "0")
end
end
-- **********************************************
-- ***** Set up all the combat text colours *****
-- **********************************************
function TriggersRecolour()
SetTriggerOption(tostring("QuowMeleeSpecialPrepare1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_prep"])))
SetTriggerOption(tostring("QuowMeleeSpecialPrepare2"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_prep"])))
SetTriggerOption(tostring("QuowMeleeSpecialPrepare3"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_prep"])))
-- You failing to prepare/do specials
SetTriggerOption(tostring("QuowMeleeSpecialFail1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_fail"])))
SetTriggerOption(tostring("QuowMeleeSpecialFail2"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_fail"])))
SetTriggerOption(tostring("QuowMeleeSpecialFail3"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_fail"])))
SetTriggerOption(tostring("QuowMeleeSpecialFail4"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_fail"])))
SetTriggerOption(tostring("QuowMeleeSpecialFail5"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_fail"])))
for iN = 1, 7 do
-- You special-hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCatSpecial" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_success"])))
-- Enemy special-hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCatSpecial" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_success"])))
-- Third party special-hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCatSpecial" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_success"])))
-- You hitting an enemy
SetTriggerOption(tostring("QuowMeleeSuccessOutCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_out_success"])))
-- Enemy hitting you
SetTriggerOption(tostring("QuowMeleeSuccessIncCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_success"])))
-- Third party hitting
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_third_success"])))
end
for iN = 1, 5 do
-- Enemy defending you special-hitting
SetTriggerOption(tostring("QuowMeleeFailOutCatSpecial" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_fail"])))
-- You defending an enemy special-hitting
SetTriggerOption(tostring("QuowMeleeFailIncCatSpecial" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_fail"])))
-- Third party defending special-hitting
SetTriggerOption(tostring("StatsMeleeFailThirdCatSpecial" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
-- Enemy defending you
SetTriggerOption(tostring("QuowMeleeFailOutCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_out_fail"])))
-- You defending an enemy
SetTriggerOption(tostring("QuowMeleeFailIncCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_fail"])))
-- Third party defending
SetTriggerOption(tostring("StatsMeleeFailThirdCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_third_fail"])))
end
for iN = 1, 3 do
-- Enemy defends your special
SetTriggerOption(tostring("QuowSpecialFailOutCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_fail"])))
-- Your special hits
SetTriggerOption(tostring("QuowSpecialSuccessOutCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_success"])))
-- You defend an enemy special
SetTriggerOption(tostring("QuowSpecialFailIncCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_fail"])))
-- Enemy hits you with a special
SetTriggerOption(tostring("QuowSpecialSuccessIncCat" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_success"])))
-- Third party defends special
SetTriggerOption(tostring("StatsSpecialFailThird" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
-- Third party hits special
SetTriggerOption(tostring("StatsSpecialSuccessThird" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_success"])))
end
for iN = 1, iCustomCombatLinesFailNormal do
if (IsTrigger("StatsMeleeFailThirdCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_out_fail"])))
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_fail"])))
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeFailThirdCat_Custom" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_third_fail"])))
end
end
for iN = 1, iCustomCombatLinesNormal do
if (IsTrigger("QuowMeleeSuccessOutCat_Custom" .. iN) == 0) then
-- You special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessOutCat_Custom" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_out_success"])))
end
if (IsTrigger("QuowMeleeSuccessIncCat_Custom" .. iN) == 0) then
-- Enemy special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("QuowMeleeSuccessIncCat_Custom" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_success"])))
end
if (IsTrigger("StatsMeleeSuccessThirdCat_Custom" .. iN) == 0) then
-- Third party special "standard" combat text (eg worm swords)
SetTriggerOption(tostring("StatsMeleeSuccessThirdCat_Custom" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_third_success"])))
end
end
for iN = 1, iCustomCombatLinesSpecial do
if (IsTrigger("QuowSpecialSuccessOutS" .. iN) == 0) then
-- You pull off a big unique special
SetTriggerOption(tostring("QuowSpecialSuccessOutS" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_success"])))
end
if (IsTrigger("QuowSpecialSuccessIncS" .. iN) == 0) then
-- Enemy pulls off a big unique special on you
SetTriggerOption(tostring("QuowSpecialSuccessIncS" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_success"])))
end
if (IsTrigger("StatsSpecialSuccessThirdS" .. iN) == 0) then
-- Third party does some big unique special
SetTriggerOption(tostring("StatsSpecialSuccessThirdS" .. iN), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_success"])))
end
end
-- You get a kill
SetTriggerOption(tostring("QuowKillStatOut1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_out_kill"])))
-- Enemy kills you
SetTriggerOption(tostring("QuowKillStatInc1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_kill"])))
-- Third party kills
SetTriggerOption(tostring("StatsKillStatThird1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_third_kill"])))
-- You defend against some unique special
SetTriggerOption(tostring("QuowSpecialFailIncCustom1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_fail"])))
-- You defend against some unique special
SetTriggerOption(tostring("QuowMiscFailInc1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_fail"])))
-- You defend against a thrown weapon
SetTriggerOption(tostring("QuowThrowingFailInc1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_fail"])))
SetTriggerOption(tostring("QuowThrowingFailInc2"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_fail"])))
SetTriggerOption(tostring("QuowThrowingFailInc3"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_melee_inc_fail"])))
-- Third party fails to prepare a special on someone
SetTriggerOption(tostring("StatsSpecialFailThirdCustom1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
SetTriggerOption(tostring("StatsSpecialFailThirdCustom2"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
-- Third party defends against third parties thrown weapon
SetTriggerOption(tostring("QuowThrowingFailThird1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
SetTriggerOption(tostring("QuowThrowingFailThird2"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
SetTriggerOption(tostring("QuowThrowingFailThird3"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
-- Ambushes, Absconds, and Backstabs
SetTriggerOption(tostring("QuowSpecialBackstabSuccessOut"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_success"])))
SetTriggerOption(tostring("QuowSpecialAmbushSuccessOut"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_success"])))
SetTriggerOption(tostring("QuowSpecialAbscondSuccessOut"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_success"])))
SetTriggerOption(tostring("QuowSpecialAmbushFailOut"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_fail"])))
SetTriggerOption(tostring("QuowSpecialBackstabSuccessInc"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_success"])))
SetTriggerOption(tostring("QuowSpecialBackstabFailInc"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_fail"])))
SetTriggerOption(tostring("QuowSpecialBackstabFail2Inc"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_fail"])))
SetTriggerOption(tostring("QuowSpecialBackstabSuccessThird"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_success"])))
SetTriggerOption(tostring("QuowSpecialAmbushSuccessThird"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_success"])))
SetTriggerOption(tostring("QuowSpecialAmbushFailThird"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_fail"])))
SetTriggerOption(tostring("QuowSpecialAbscondSuccessThird"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_third_success"])))
-- Feints
SetTriggerOption(tostring("QuowFeintSuccessIncoming1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_success"])))
SetTriggerOption(tostring("QuowFeintFailIncoming1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_inc_fail"])))
SetTriggerOption(tostring("QuowFeintFailOutgoing1"), "other_text_colour", tostring(ColourNameToRGB(sUSER_OPTIONS["col_special_out_fail"])))
end
-- *****************************************
-- ***** Combat Stats full text report *****
-- *****************************************
function GenerateStatsReport()
ColourNote(iGlobalColourSilver, "", "Full Combat Stats for stat set " .. iCurrentCombatStatSet .. " '" .. iQuowCombatStats[iCurrentCombatStatSet]["set_name"] .. "':")
ColourNote(iGlobalColourSilver, "", "Stat: Enemies: You:")
ColourNote(sGlobalColourOrange, "", "=-=-==-=-=-=-=-=-=-=-=-= =-=-=-=-=-=- =-=-=-=-=-=-")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "Total Kills:"))
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["deaths_total"]))
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["kills_total"])
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "Total Rounds:"))
ColourTell(sGlobalColourRed, "", string.format("%-13s ", "-"))
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"])
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "..Hits Per Round:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
ColourTell(sGlobalColourGreen, "", sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "..Kills Per Round:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["deaths_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["kills_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
ColourTell(sGlobalColourGreen, "", sPerc)
Note("")
local iTotalSpecials = iQuowCombatStats[iCurrentCombatStatSet]["special_out_prepared"] + iQuowCombatStats[iCurrentCombatStatSet]["special_out_failprepared"]
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "Total Special Prepares:"))
ColourTell(sGlobalColourRed, "", string.format("%-13s ", "-"))
ColourTell(sGlobalColourGreen, "", iTotalSpecials)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "...Successful Prepares:"))
ColourTell(sGlobalColourRed, "", string.format("%-13s ", "-"))
sPerc = (iTotalSpecials > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["special_out_prepared"] / iTotalSpecials * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["special_out_prepared"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "...Failed Prepares:"))
ColourTell(sGlobalColourRed, "", string.format("%-13s ", "-"))
sPerc = (iTotalSpecials > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["special_out_failprepared"] / iTotalSpecials * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["special_out_failprepared"] .. sPerc)
Note("")
local iTotalSpecialsOut = iQuowCombatStats[iCurrentCombatStatSet]["special_out_landed"] + iQuowCombatStats[iCurrentCombatStatSet]["special_out_defended"]
local iTotalSpecialsInc = iQuowCombatStats[iCurrentCombatStatSet]["special_inc_landed"] + iQuowCombatStats[iCurrentCombatStatSet]["special_inc_defended"]
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "Total Specials Against:"))
ColourTell(sGlobalColourGreen, "", string.format("%-13s ", iTotalSpecialsOut))
ColourTell(sGlobalColourRed, "", iTotalSpecialsInc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "...Specials Landed On:"))
sPerc = (iTotalSpecialsOut > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["special_out_landed"] / iTotalSpecialsOut * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["special_out_landed"] .. sPerc))
sPerc = (iTotalSpecialsInc > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["special_inc_landed"] / iTotalSpecialsInc * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", iQuowCombatStats[iCurrentCombatStatSet]["special_inc_landed"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "...Specials Defended By:"))
sPerc = (iTotalSpecialsOut > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["special_out_defended"] / iTotalSpecialsOut * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["special_out_defended"] .. sPerc))
sPerc = (iTotalSpecialsInc > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["special_inc_defended"] / iTotalSpecialsInc * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["special_inc_defended"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "Total Hit Attempts:"))
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"]))
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"])
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "...Hits Landed:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "...Hits Defended:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......Dodged:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] .. sPerc)
Note("")
-- Break down the dodges
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Barely:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_barely"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_barely"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_barely"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_barely"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Average:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_normal"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_normal"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_normal"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_normal"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Good:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_deftly"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_deftly"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_deftly"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_deftly"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Somehow Avoid:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_somehow"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged_somehow"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_somehow"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged_somehow"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......Parried:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] .. sPerc)
Note("")
-- Break down the parries
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Barely:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried_barely"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried_barely"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried_barely"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried_barely"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Average:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried_normal"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried_normal"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried_normal"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried_normal"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Good:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried_deftly"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried_deftly"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried_deftly"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried_deftly"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......Blocked:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] .. sPerc)
Note("")
-- Break down the blocks
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Barely:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked_barely"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked_barely"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked_barely"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked_barely"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Average:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked_normal"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked_normal"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked_normal"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked_normal"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", ".........Good:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked_deftly"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked_deftly"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked_deftly"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked_deftly"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......Zone Focus:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......TPA:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_tpa"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_tpa"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_tpa"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_tpa"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......Major:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_major"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_major"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_major"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_major"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......Bug Shield:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_bugs"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_bugs"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_bugs"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_bugs"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......EFF:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_eff"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_eff"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_eff"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_eff"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......CCC Full Absorb:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_ccc"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_ccc"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_ccc"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_ccc"] .. sPerc)
Note("")
ColourTell(iGlobalColourSilver, "", string.format("%-25s ", "......Armour Full Absorb:"))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_armoured"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourRed, "", string.format("%-13s ", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_armoured"] .. sPerc))
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_armoured"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
ColourTell(sGlobalColourGreen, "", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_armoured"] .. sPerc)
Note("")
end
-- ****************************************
-- ***** Combat Stats window handling *****
-- ****************************************
function RedrawStatsWindow()
-- Save effort, do nothing if not showing this window
if (WINDATA[winStats]["SHOW"] == false) then
return
end
-- Clear the window afresh and draw a new border
WindowRectOp(winStats, miniwin.rect_fill, 0, 0, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], iGlobalColourBlack)
local sPerc
local iY = 2
local sUseFont
local iThisLineHeight = iGlobalLineHeight
if (WINDATA[winStats]["WIDTH"] < 250 or WINDATA[winStats]["HEIGHT"] < 200) then
sUseFont = "bodyfont"..winStats
elseif (WINDATA[winStats]["WIDTH"] < 400 or WINDATA[winStats]["HEIGHT"] < 300) then
sUseFont = "bodyfont"..winStats.."m"
iThisLineHeight = iThisLineHeight + 3
else
sUseFont = "bodyfont"..winStats.."l"
iThisLineHeight = iThisLineHeight + 7
end
local iCheckWidth = WindowTextWidth(winStats, sUseFont, "Total Rounds:")
local iCol1 = 2
local iCol2 = iCheckWidth + 4
local iCol3 = math.floor(2 + (WINDATA[winStats]["WIDTH"] * 0.65))
WindowText(winStats, sUseFont, "Stats for set '" .. tostring(iQuowCombatStats[iCurrentCombatStatSet]["set_name"]) .. "' [" .. iCurrentCombatStatSet .. "]", 2, iY, 0, 0, iGlobalColourSilver, false)
iY = iY + iThisLineHeight
-- Is window big enough for side by side columns or not?
if (iCheckWidth >= (WINDATA[winStats]["WIDTH"] * 0.3)) then
iCol3 = iCol2
WindowText(winStats, sUseFont, "Stat: ", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, "You: ", iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Kills:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["kills_total"], iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Hits/Round:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
WindowText(winStats, sUseFont, sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Total Rounds:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"], iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Total Hits:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"], iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Landed:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Defended:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Dodged:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Parried:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Blocked:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Focus:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..TPA:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_tpa"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_tpa"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Major:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_major"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_major"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Bugs:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_bugs"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_bugs"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..EFF:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_eff"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_eff"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..CCC:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_ccc"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_ccc"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Armour:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_armoured"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_armoured"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Stat: ", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, "Enemies: ", iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Kills:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["deaths_total"], iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Hits/Round:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
WindowText(winStats, sUseFont, sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Total Hits:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"], iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Landed:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Defended:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Dodged:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Parried:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Blocked:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Focus:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..TPA:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_tpa"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_tpa"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Major:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_major"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_major"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Bugs:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_bugs"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_bugs"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..EFF:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_eff"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_eff"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..CCC:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_ccc"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_ccc"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Armour:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_armoured"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_armoured"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
iY = iY + iThisLineHeight
else
WindowText(winStats, sUseFont, "Stat: ", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, "Enemies: ", iCol2, iY, 0, 0, iGlobalColourRed, false)
WindowText(winStats, sUseFont, "You: ", iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Kills:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["deaths_total"], iCol2, iY, 0, 0, iGlobalColourRed, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["kills_total"], iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Hits/Round:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
WindowText(winStats, sUseFont, sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"] > 0) and string.format("%.2f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] / iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"]) or "0"
WindowText(winStats, sUseFont, sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Total Rounds:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["rounds_total"], iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Total Hits:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"], iCol2, iY, 0, 0, iGlobalColourRed, false)
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"], iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Landed:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "Defended:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Dodged:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_dodged"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_dodged"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Parried:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_parried"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_parried"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Blocked:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended_blocked"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended_blocked"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Focus:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..TPA:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_tpa"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_tpa"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_tpa"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_tpa"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Major:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_major"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_major"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_major"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_major"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Bugs:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_bugs"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_bugs"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_bugs"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_bugs"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..EFF:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_eff"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_eff"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_eff"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_eff"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..CCC:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_ccc"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_ccc"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_ccc"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_ccc"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
WindowText(winStats, sUseFont, "..Armour:", iCol1, iY, 0, 0, iGlobalColourSilver, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_out_armoured"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_out_armoured"] .. sPerc, iCol2, iY, 0, 0, iGlobalColourRed, false)
sPerc = (iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] > 0) and " [" .. string.format("%.1f", iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_armoured"] / iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] * 100) .. "%]" or " [0%]"
WindowText(winStats, sUseFont, iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_armoured"] .. sPerc, iCol3, iY, 0, 0, iGlobalColourGreen, false)
iY = iY + iThisLineHeight
end
-- Border the whole window
WindowRectOp(winStats, miniwin.rect_frame, 0, 0, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
end
-- *****************************************
-- ***** Draw Disc Date on the Minimap *****
-- *****************************************
function UpdateDiscDate()
-- Update Disc game date if needed
if (bShowDiscDate == true) then
DrawDiscDate(true)
Repaint()
end
end
function DrawDiscDate(bRedoBrightness)
local iSeconds, iMinutes, iHours, sAMPM, iHoursTwelve, iDayInYear, iDayInWeek, iYears, iCycle, iMonth, iDayInMonth, sDiscMonth, sDiscShortMonth, sDiscDay, sDiscShortDay, sDiscCycle, sDiscShortCycle, sDay = UnixTimeDiscTime()
local sDiscGameTime = iHoursTwelve .. ":" .. string.format("%02d", iMinutes) .. sAMPM .. " "
local sDiscGameDateLong = sDay .. " " .. DateOrdinal(iDayInMonth) .. " " .. sDiscMonth -- .. " " .. sDiscCycle .. " UC " .. iYears
local sDiscGameDateShort = sDiscShortDay .. " " .. DateOrdinal(iDayInMonth) .. " " .. sDiscShortMonth -- .. " " .. sDiscShortCycle .. " UC " .. iYears
local iCheckWidthTime = WindowTextWidth(winMinimap, "bodyfont"..winMinimap, sDiscGameTime)
local iCheckWidthDateLong = WindowTextWidth(winMinimap, "bodyfont"..winMinimap, sDiscGameDateLong)
local iCheckWidthDateShort = WindowTextWidth(winMinimap, "bodyfont"..winMinimap, sDiscGameDateShort)
local iDrawHeight = iGlobalLineHeight
if ((iCheckWidthTime + iCheckWidthDateLong) <= WINDATA[winMinimap]["WIDTH"]) then
WindowRectOp(winMinimap, miniwin.rect_fill, 1, WINDATA[winMinimap]["HEIGHT"] - iDrawHeight, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], iGlobalColourWhite)
WindowText(winMinimap, "bodyfont"..winMinimap, sDiscGameTime .. sDiscGameDateLong, 1, WINDATA[winMinimap]["HEIGHT"] - iGlobalLineHeight, 0, 0, 0, false)
elseif ((iCheckWidthTime + iCheckWidthDateShort) <= WINDATA[winMinimap]["WIDTH"]) then
WindowRectOp(winMinimap, miniwin.rect_fill, 1, WINDATA[winMinimap]["HEIGHT"] - iDrawHeight, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], iGlobalColourWhite)
WindowText(winMinimap, "bodyfont"..winMinimap, sDiscGameTime .. sDiscGameDateShort, 1, WINDATA[winMinimap]["HEIGHT"] - iGlobalLineHeight, 0, 0, 0, false)
else
iDrawHeight = iGlobalLineHeight * 2
WindowRectOp(winMinimap, miniwin.rect_fill, 1, WINDATA[winMinimap]["HEIGHT"] - iDrawHeight, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], iGlobalColourWhite)
WindowText(winMinimap, "bodyfont"..winMinimap, sDiscGameTime, 1, WINDATA[winMinimap]["HEIGHT"] - (iGlobalLineHeight * 2), 0, 0, 0, false)
WindowText(winMinimap, "bodyfont"..winMinimap, sDiscGameDateShort, 1, WINDATA[winMinimap]["HEIGHT"] - iGlobalLineHeight, 0, 0, 0, false)
end
WindowLine (winMinimap, 0, WINDATA[winMinimap]["HEIGHT"] - iDrawHeight, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"] - iDrawHeight, 0, 0, 1)
-- Change brightness of the freshly drawn date box window
if (bRedoBrightness == true and iMinimapBrightness < 100) then
WindowFilter (winMinimap, 0, WINDATA[winMinimap]["HEIGHT"] - iDrawHeight, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], 21, (iMinimapBrightness / 100))
end
end
-- **************************************************
-- ***** Generate Discworld Date from real time *****
-- **************************************************
-- Discworld month names
sDiscMonthNames = { [0] = "Offle", "February", "March", "April", "May", "June", "Grune", "August", "Spune", "Sektober", "Ember", "December", "Ick", "Off", "Feb", "Mar", "Apr", "May", "Jun", "Gru", "Aug", "Spu", "Sek", "Emb", "Dec", "Ick" }
-- Discworld day names
sDiscDayNames = { [0] = "Octeday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Oct", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }
-- Discworld days-per-month
iDiscDaysPerMonth= { [0] = 32,32,32,32,32,32,32,32,32,32,32,32,16 }
-- Discworld prime year cycles
sDiscCycles = { [0] = "Prime", "Secundus", "I", "II" }
-- Ordinals
sDateOrdinals = {"st", "nd", "rd"}
-- Generate the ordinal string, nd, th etc. to a given day number
function DateOrdinal(iDay)
local iDigit = tonumber(string.sub(iDay, -1))
if (iDigit > 0 and iDigit <= 3 and iDay ~= 11 and iDay ~= 12 and iDay ~= 13) then
return iDay .. sDateOrdinals[iDigit]
else
return iDay .. "th"
end
end
function UnixTimeDiscTime( iRealTime )
-- If no timestamped passed, default to current time
if (iRealTime == nil) then
iRealTime = os.time()
end
local fmod, floor = math.fmod, math.floor
-- Convert time (in seconds) to the different time elements
local iSeconds = floor(fmod(iRealTime, 18))
local iMinutes = floor(fmod(iRealTime, 18*60)/18)
local iHours = floor(fmod(iRealTime, 18*60*24)/(18*60))
local iHoursTwelve = fmod(iHours, 12)
if (iHoursTwelve == 0) then iHoursTwelve = 12 end
local sAMPM = (iHours > 11) and "pm" or "am"
local iDayInYear = floor(fmod(iRealTime, 18*60*24*400)/(18*60*24))
local iDayInWeek = floor(fmod(iRealTime+(18*60*24*5), 18*60*24*8)/(18*60*24))
local iYears = floor(iRealTime/(18*60*24*400*2)) + 1966
local iCycle = floor(fmod((iRealTime/(18*60*24*400)),2))
-- Calculate which month the time is in
local iTotalDays = iDayInYear
local iMonth = 0
while (iTotalDays >= iDiscDaysPerMonth[iMonth]) do
iTotalDays = iTotalDays - iDiscDaysPerMonth[iMonth]
iMonth = iMonth + 1
end
iDayInMonth = iTotalDays + 1
-- Get the special day name else the normal day name
local sSpecialDay, sDayName
if iMonth==0 and iDayInMonth==1 then
if iCycle==0 then sSpecialDay = "Hogswatch"
else sSpecialDay = "Crueltide"
end
end
if (iMonth == 6 and iDayInMonth == 16) then
sSpecialDay = "Small Gods day"
end
if (iMonth == 7 and iDayInMonth == 23) then
sSpecialDay = "Soul Cake Tuesday"
end
if (iMonth == 9 and iDayInMonth == 1) then
sSpecialDay = "Sektober Fools' Day"
end
if (sSpecialDay) then
sDayName = sSpecialDay
else
sDayName = sDiscDayNames[iDayInWeek]
end
-- Return it all
return iSeconds, iMinutes, iHours, sAMPM, iHoursTwelve, iDayInYear, iDayInWeek, iYears, iCycle, iMonth, iDayInMonth, sDiscMonthNames[iMonth], sDiscMonthNames[iMonth + 13], sDiscDayNames[iDayInWeek], sDiscDayNames[iDayInWeek+8], sDiscCycles[iCycle], sDiscCycles[iCycle+2], sDayName
end
function OnPluginPacketReceived (sText)
--ColourNote("magenta", "", sText)
end -- function
-- ***********************************
-- ***** Redraw Ascii Map Window *****
-- ***********************************
iAsciiMapLines = 0
sASCIIMapLineStyles = {}
sAsciiMapString = ""
bAsciiFoundMatch = true
bAsciiShownWarning = false
iASCIIWidth = 0
iAsciiPlayerX = 0
iAsciiPlayerY = 0
bAsciiSeenYellow = false
iMUDYellow = ColourNameToRGB("yellow")
function RedrawAsciiWindow()
-- Save effort, do nothing if not showing this window
if (WINDATA[winAscii]["SHOW"] == false) then
return
end
WindowRectOp(winAscii, miniwin.rect_fill, 0, 0, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], iGlobalColourBlack)
WindowRectOp(winAscii, miniwin.rect_frame, 0, 0, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
if (#sASCIIMapLineStyles ~= 0) then
-- map display
local iAsciiWidth = iASCIIWidth * iGlobalFontWidth
local iAsciiHeight = #sASCIIMapLineStyles * iGlobalLineHeight
local iAsciiPlayerCentreX = (iAsciiWidth / 2) - ((iAsciiPlayerX * iGlobalFontWidth) - (iGlobalFontWidth / 2))
local iAsciiPlayerCentreY = (iAsciiHeight / 2) - ((iAsciiPlayerY * iGlobalLineHeight) - (iGlobalLineHeight / 2))
local iAddLeft = ((WINDATA[winAscii]["WIDTH"] - iAsciiWidth) / 2) + iAsciiPlayerCentreX
local iAddTop = ((WINDATA[winAscii]["HEIGHT"] - iAsciiHeight) / 2) + iAsciiPlayerCentreY
local iLeft, iTop
for iLineNum, sStyleData in ipairs (sASCIIMapLineStyles) do
iLeft, iTop = iAddLeft, (iAddTop + ((iLineNum - 1) * iGlobalLineHeight))
for _, sThisStyle in ipairs (sStyleData) do
iLeft = iLeft + WindowText (winAscii, "bodyfont"..winAscii, sThisStyle.text, iLeft, iTop, 0, 0, sThisStyle.textcolour)
end
end
else
WindowText (winAscii, "bodyfont"..winAscii, "@", (WINDATA[winAscii]["WIDTH"] - iGlobalFontWidth) / 2, (WINDATA[winAscii]["HEIGHT"] - iGlobalLineHeight) / 2, 0, 0, iGlobalColourSilver)
end
end
-- Handle map redirection triggers
function HandleAsciiMapRedirection (sName, sLine, sWildcards, objStyles)
-- Insert THIS map line into the map table, objStyles and all
bAsciiFoundMatch = true
table.insert (sASCIIMapLineStyles, objStyles)
if (string.len(sLine) > iASCIIWidth) then
iASCIIWidth = string.len(sLine)
end
-- Find player location - ideally a yellow one, if not then any @ symbol
if (bAsciiSeenYellow == false) then
local iTempXPos, iWhereAt = 0, 0
for iStyleKey, sThisStyle in ipairs (objStyles) do
iWhereAt = string.find(sThisStyle.text, "@")
if (sThisStyle.text == "@" and sThisStyle.textcolour == iMUDYellow) then
bAsciiSeenYellow = true
iAsciiPlayerX = iTempXPos + 1
iAsciiPlayerY = #sASCIIMapLineStyles
break
elseif (bAsciiSeenYellow == false and iWhereAt ~= nil) then
iAsciiPlayerX = iWhereAt + iTempXPos
iAsciiPlayerY = #sASCIIMapLineStyles
end
iTempXPos = iTempXPos + string.len(sThisStyle.text)
end
end
-- Final line?
iAsciiMapLines = iAsciiMapLines - 1
if (iAsciiMapLines == 0) then
EnableTrigger("AsciiMapLine", false)
RedrawAsciiWindow()
end
end
-- ******************************************
-- ***** Handle External Function Comms *****
-- ******************************************
function HandleExternalComms(sThisData)
local objThisData = json.decode(sThisData)
local sMessageType, sLine, sStyles = objThisData[1], objThisData[2], objThisData[3]
if (iCommsCountByType[sMessageType] ~= nil) then
HandleCommsMessage("CommLog_" .. sMessageType, sLine, "", sStyles)
end
end
-- Special handlers for newbie-tell, cre-tell, and special-tell
function QuowOutgoingCreTell(sName, sLine, sWildcards, objStyles)
local objEncoded = json.encode({"cre", sLine, objStyles})
HandleExternalComms(objEncoded)
end
function QuowOutgoingNewbieTell(sName, sLine, sWildcards, objStyles)
local objEncoded = json.encode({"newbie", sLine, objStyles})
HandleExternalComms(objEncoded)
end
function QuowOutgoingSpecialTell(sName, sLine, sWildcards, objStyles)
local objEncoded = json.encode({"special", sLine, objStyles})
HandleExternalComms(objEncoded)
end
-- ******************************************
-- ***** Handle Incoming/Outgoing Tells *****
-- ******************************************
-- Handle tells incoming/outgoing to split chat?
sCommsBuffer = {}
function HandleCommsMessage(sName, sLine, objWildcards, objStyles)
sName = string.gsub(string.sub(sName, 9), "_ZXA_", "-")
iCommsCountByType[sName] = iCommsCountByType[sName] + 1
table.insert(objStyles, 1, {["textcolour"] = iGlobalColourGrey, ["backcolour"] = 0, ["text"] = os.date ("%H:%M:%S: "), ["length"] = 10})
table.insert(sCommsBuffer, {sName, (string.len(sLine) + 10), objStyles, os.time()})
-- Delete buffer above 10000 lines
if (#sCommsBuffer > 10000) then
iCommsCountByType[sName] = iCommsCountByType[sName] - 1
table.remove(sCommsBuffer, 1)
if (objChatFilters[sName][2] == true) then
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown - 1
end
end
if (objChatFilters[sName][2] == true) then
if (iCommLineBottomRender == iCommsMessagesCurrentlyShown) then
iCommLineBottomRender = iCommLineBottomRender + 1
end
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + 1
-- Redraw the window
RedrawCommsWindow()
end
end
-- *******************************
-- ***** Redraw Comms Window *****
-- *******************************
require "wait"
bCommWindowIsScrolling = false
bCommWindowDragScrolling = false
iCommWindowLines = 0
iCommLinesRendered = 0
iCommLineBottomRender = 0
iCommMaxLines = 0
iCommLineClicked = 0
iBarPos = 0
iBarSize = 0
iCommScrollClickY = 0
SCROLL_BAR_HEIGHT = 0
SCROLL_BAR_WIDTH = 15
sPolyPoints = ""
-- Handle the scrollbar being dragged around
function ScrollerMoveCallback(flags, hotspot_id)
local iThisMouseY = WindowInfo(winComms, 18)
local iCommWindowTop = WindowInfo(winComms, 2)
iBarPos = math.max(iThisMouseY-iCommWindowTop+iCommScrollClickY, SCROLL_BAR_WIDTH+iTopCommsWindow)
if iBarPos > WINDATA[winComms]["HEIGHT"]-SCROLL_BAR_WIDTH-iBarSize then
iBarPos = WINDATA[winComms]["HEIGHT"]-SCROLL_BAR_WIDTH-iBarSize
iCommLineBottomRender = iCommsMessagesCurrentlyShown
else
local iLineStart = math.floor((iBarPos-SCROLL_BAR_WIDTH-iTopCommsWindow)/(SCROLL_BAR_HEIGHT/iCommMaxLines)+1)
iCommLineBottomRender = math.min(iLineStart + iCommLinesRendered-1, iCommsMessagesCurrentlyShown)
end
RedrawCommsWindow()
end
-- The user let go of the scrollbar
function ScrollerReleaseCallback(flags, hotspot_id)
bCommWindowDragScrolling = false
RedrawCommsWindow()
end -- function ScrollerReleaseCallback
-- Handle clicking the up and down arrows and holding them down
function scrollbar(calledBy)
wait.make (function()
while bCommWindowIsScrolling == true do
if calledBy == "hsCommsUp" then
if (iCommLineBottomRender > iCommLinesRendered) then
iCommLineBottomRender = iCommLineBottomRender - 1
WindowRectOp(winComms, miniwin.rect_draw_edge, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)-1, iTopCommsWindow, -1, SCROLL_BAR_WIDTH + iTopCommsWindow,
miniwin.rect_edge_sunken, miniwin.rect_edge_at_all + miniwin.rect_option_fill_middle) -- up arrow pushed
sPolyPoints = string.format ("%i,%i,%i,%i,%i,%i", (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+1, 8+iTopCommsWindow, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+5, 4+iTopCommsWindow, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+9, 8+iTopCommsWindow)
WindowPolygon (winComms, sPolyPoints,
winThemeData.DETAIL, miniwin.pen_solid, 1, -- pen (solid, width 1)
winThemeData.DETAIL, miniwin.brush_solid, -- brush (solid)
true, -- close
false) -- alt fill
else
bCommWindowIsScrolling = false
end
elseif calledBy == "hsCommsDown" then
if (iCommLineBottomRender < iCommsMessagesCurrentlyShown) then
iCommLineBottomRender = iCommLineBottomRender + 1
WindowRectOp(winComms, miniwin.rect_draw_edge, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)-1, WINDATA[winComms]["HEIGHT"]-(SCROLL_BAR_WIDTH), -1, WINDATA[winComms]["HEIGHT"]-1,
miniwin.rect_edge_sunken, miniwin.rect_edge_at_all + miniwin.rect_option_fill_middle) -- down arrow pushed
sPolyPoints = string.format ("%i,%i,%i,%i,%i,%i", (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+1, WINDATA[winComms]["HEIGHT"]-10,(WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+5, WINDATA[winComms]["HEIGHT"]-6, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+9,WINDATA[winComms]["HEIGHT"]-10)
WindowPolygon (winComms, sPolyPoints,
winThemeData.DETAIL, miniwin.pen_solid, 1, -- pen (solid, width 1)
winThemeData.DETAIL, miniwin.brush_solid, -- brush (solid)
true, -- close
false) -- alt fill
else
bCommWindowIsScrolling = false
end
end -- if
wait.time(0.1)
RedrawCommsWindow()
end -- while bCommWindowIsScrolling
end) -- wait.make
end -- function scrollbar
-- Releasing the scrollbar up/down buttons
function CommsMouseUp(flags, hotspot_id)
bCommWindowIsScrolling = false
bCommsNeedsButtons = true
RedrawCommsWindow()
end
-- Communications window scroll bar clicking
function CommsMouseDown(flags, hotspot_id)
if (hotspot_id == "hsCommScroller") then
iCommScrollClickY = WindowHotspotInfo(winComms, "hsCommScroller", 2)-WindowInfo(winComms, 15)
bCommWindowDragScrolling = true
else
bCommWindowIsScrolling = true
scrollbar(hotspot_id)
end
end
-- Mouse up on the chat-tabs bar, handle changing channels
function ChatTabMouseUp(flags, hotspot_id)
if (bit.band(flags, miniwin.hotspot_got_rh_mouse) ~= 0) then
winInfoComms.mouseup(flags, hotspot_id)
else
local iChannelWidth = math.floor((WINDATA[winComms]["WIDTH"] - 8) / #objChatTabs)
if (iChannelWidth < 30) then
iChannelWidth = 30
end
local iChanMouseX = WindowInfo(winComms, 14)
ChangeChatChannel(math.ceil(iChanMouseX / iChannelWidth))
RedrawCommsWindow()
end
end
-- Function to change the chat channel and update the messages (does NOT call RedrawCommsWindow afterwards - do that after!)
function ChangeChatChannel(iNewChannel)
iCurrentChannelChoice = iNewChannel
local iCheckChannel = 0
iCommsMessagesCurrentlyShown = 0
for sKey, sData in pairs(objChatFilters) do
objChatFilters[sKey][2] = false
end
for sTabKey, sTabData in ipairs(objChatTabs[iCurrentChannelChoice][2]) do
if (sTabData == "*All*") then
iCommsMessagesCurrentlyShown = 0
for sKey, sData in pairs(objChatFilters) do
objChatFilters[sKey][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sKey]
end
break
elseif (sTabData == "*Talkers*") then
for sKey, sData in pairs(objChatFilters) do
if (sKey ~= "Tells_In" and sKey ~= "Tells_Out" and sKey ~= "Group_Say") then
objChatFilters[sKey][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sKey]
end
end
else
objChatFilters[sTabData][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sTabData]
end
end
iCommLineBottomRender = iCommsMessagesCurrentlyShown
end
-- Main re-draw function to actually SHOW the messages and tabs and scrollbar etc.
bCommsNeedsButtons = true
function RedrawCommsWindow(iGrabLineNumber)
iCommWindowLines = math.floor((WINDATA[winComms]["HEIGHT"] - 2) / iGlobalLineHeight)
-- Save effort, do nothing if not showing this window
if (WINDATA[winComms]["SHOW"] == false) then
return
end
WindowRectOp(winComms, miniwin.rect_fill, 0, iTopCommsWindow, WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH+1), WINDATA[winComms]["HEIGHT"], iGlobalColourBlack)
-- Scrollbar base
WindowRectOp(winComms, miniwin.rect_fill, WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH-1, SCROLL_BAR_WIDTH+iTopCommsWindow, WINDATA[winComms]["WIDTH"]-1, WINDATA[winComms]["HEIGHT"] - SCROLL_BAR_WIDTH, winThemeData.BACK_FACE) -- scroll bar background
WindowRectOp(winComms, miniwin.rect_frame, WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH, SCROLL_BAR_WIDTH+1+iTopCommsWindow, WINDATA[winComms]["WIDTH"]-2, WINDATA[winComms]["HEIGHT"]-(SCROLL_BAR_WIDTH)-1, winThemeData.DETAIL) -- scroll bar background inset rectangle
if (bCommsNeedsButtons == true) then
-- draw triangle in up button
DrawThemed3DRect(winComms, WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH-1, iTopCommsWindow, WINDATA[winComms]["WIDTH"]-1, SCROLL_BAR_WIDTH + iTopCommsWindow) -- top scroll button
sPolyPoints = string.format ("%i,%i,%i,%i,%i,%i", (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+1, iTopCommsWindow+8, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+5, iTopCommsWindow+4, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+9, iTopCommsWindow+8)
WindowPolygon (winComms, sPolyPoints,
winThemeData.DETAIL, miniwin.pen_solid, 1, -- pen (solid, width 1)
winThemeData.DETAIL, miniwin.brush_solid, --brush (solid)
true, --close
false) --alt fill
-- draw triangle in down button
DrawThemed3DRect(winComms, WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH-1, WINDATA[winComms]["HEIGHT"]-SCROLL_BAR_WIDTH, WINDATA[winComms]["WIDTH"]-1, WINDATA[winComms]["HEIGHT"]) -- bottom scroll button
sPolyPoints = string.format ("%i,%i,%i,%i,%i,%i", (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+1, WINDATA[winComms]["HEIGHT"]-10,(WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+5, WINDATA[winComms]["HEIGHT"]-6, (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH)+9,WINDATA[winComms]["HEIGHT"]-10)
WindowPolygon (winComms, sPolyPoints,
winThemeData.DETAIL, miniwin.pen_solid, 1, -- pen (solid, width 1)
winThemeData.DETAIL, miniwin.brush_solid, --brush (solid)
true, --close
false) --alt fill
bCommsNeedsButtons = false
end
local iTX = 1
local iTY = WINDATA[winComms]["HEIGHT"] - (iGlobalLineHeight + 2)
local iMaxWidth = math.floor((WINDATA[winComms]["WIDTH"] - (iTX + 2 + SCROLL_BAR_WIDTH)) / iGlobalFontWidth)
local iTotalLinesNeeded = 0
local iTotalLinesAdded = 0
local iSpaceLeft = 0
local iSpaceEat = 0
local iLengthLeft = 0
local sRemainingText = ""
local sThisText = ""
local iGrabThisLineNumber = 0
iCommLinesRendered = 0
local iColTop = 0
local iColBot = 0
local iLinesToRenderFrom = 0
local iLinesToSkip = iCommsMessagesCurrentlyShown - iCommLineBottomRender
-- Loop backwards through the comms table
for iC = #sCommsBuffer, 1, -1 do
-- Is this a type of message we CURRENTLY want to display?
if (objChatFilters[sCommsBuffer[iC][1]] and objChatFilters[sCommsBuffer[iC][1]][2] == true) then
if (iLinesToSkip == 0) then
iLinesToRenderFrom = iC
break
end
iLinesToSkip = iLinesToSkip - 1
end
end
for iC = iLinesToRenderFrom, 1, -1 do
-- Is this a type of message we CURRENTLY want to display?
if (objChatFilters[sCommsBuffer[iC][1]] and objChatFilters[sCommsBuffer[iC][1]][2] == true) then
-- Set up the positions
iTX = 1
iTotalLinesAdded = math.ceil(sCommsBuffer[iC][2] / iMaxWidth)
iTotalLinesNeeded = iTotalLinesAdded - 1
iSpaceLeft = iMaxWidth
if (iSpaceLeft < 1) then
iSpaceLeft = 1
end
-- Loop through the styles
for iStyleKey, sThisStyle in ipairs (sCommsBuffer[iC][3]) do
iLengthLeft = sThisStyle.length
sRemainingText = sThisStyle.text
-- This style takes us over the edge, split it
if (iLengthLeft > iSpaceLeft) then
iSpaceEat = iSpaceLeft
while (sRemainingText ~= "") do
sThisText = string.sub(sRemainingText, 1, iSpaceEat)
iLengthLeft = iLengthLeft - iSpaceEat
sRemainingText = string.sub(sRemainingText, iSpaceEat + 1)
-- Background colour?
if (sThisStyle.backcolour ~= 0) then
iColTop = iTY - (iTotalLinesNeeded * iGlobalLineHeight)
if (iColTop < iTopCommsWindow) then
iColTop = 0
end
iColBot = iTY - ((iTotalLinesNeeded - 1) * iGlobalLineHeight)
if (iColBot < 0) then
iColBot = 0
end
if (iColBot ~= iColTop) then
WindowRectOp(winComms, miniwin.rect_fill, iTX, iColTop, iTX + (iSpaceEat * iGlobalFontWidth), iColBot, sThisStyle.backcolour)
end
end
iTX = iTX + WindowText(winComms, "bodyfont"..winComms, sThisText, iTX, iTY - (iTotalLinesNeeded * iGlobalLineHeight), 0, 0, sThisStyle.textcolour, false)
if (iGrabLineNumber ~= nil and iGrabLineNumber >= iTY - (iTotalLinesNeeded * iGlobalLineHeight) and iGrabLineNumber <= iTY - ((iTotalLinesNeeded - 1) * iGlobalLineHeight)) then
iGrabThisLineNumber = iC
end
if (iLengthLeft ~= 0) then
iTotalLinesNeeded = iTotalLinesNeeded - 1
iTX = 1
iSpaceEat = iLengthLeft
if (iSpaceEat > iMaxWidth) then
iSpaceEat = iMaxWidth
end
else
iSpaceLeft = iMaxWidth - iSpaceEat
end
end
else
-- This style fits nicely, add it on, count the space left
iSpaceLeft = iSpaceLeft - iLengthLeft
-- Background colour?
if (sThisStyle.backcolour ~= 0) then
iColTop = iTY - (iTotalLinesNeeded * iGlobalLineHeight)
if (iColTop < 0) then
iColTop = 0
end
iColBot = iTY - ((iTotalLinesNeeded - 1) * iGlobalLineHeight)
if (iColBot < 0) then
iColBot = 0
end
if (iColBot ~= iColTop) then
WindowRectOp(winComms, miniwin.rect_fill, iTX, iColTop, iTX + (iLengthLeft * iGlobalFontWidth), iColBot, sThisStyle.backcolour)
end
end
iTX = iTX + WindowText(winComms, "bodyfont"..winComms, sRemainingText, iTX, iTY - (iTotalLinesNeeded * iGlobalLineHeight), 0, 0, sThisStyle.textcolour, false)
if (iGrabLineNumber ~= nil and iGrabLineNumber >= iTY - (iTotalLinesNeeded * iGlobalLineHeight) and iGrabLineNumber <= iTY - ((iTotalLinesNeeded - 1) * iGlobalLineHeight)) then
iGrabThisLineNumber = iC
end
end
end
-- Move up by the total number of lines
iTY = iTY - (iTotalLinesAdded * iGlobalLineHeight)
-- And stop going back if we're going beyond a whole line worth off the top edge
if (iTY <= -iGlobalLineHeight) then
break
else
iCommLinesRendered = iCommLinesRendered + 1
end
end
end
-- Display the chat tabs
if (bShowCommsTabs == true) then
WindowRectOp(winComms, miniwin.rect_fill, 0, 0, WINDATA[winComms]["WIDTH"], iTopCommsWindow, iGlobalColourBlack)
local iChannelWidth = math.floor((WINDATA[winComms]["WIDTH"] - 8) / #objChatTabs)
if (iChannelWidth < 30) then
iChannelWidth = 30
end
local iChanX = 0
for iN = 1, #objChatTabs do
if (iCurrentChannelChoice == iN) then
WindowRectOp(winComms, miniwin.rect_fill, iChanX, 0, iChanX + iChannelWidth, iTopCommsWindow, winThemeData.FACE)
WindowText(winComms, "bodyfont"..winComms, objChatTabs[iN][1], iChanX + 2, 1, 0, 0, iGlobalColourBlack, false)
else
DrawThemed3DRect(winComms, iChanX, 0, iChanX + iChannelWidth, iTopCommsWindow)
WindowText(winComms, "bodyfont"..winComms, objChatTabs[iN][1], iChanX + 2, 2, 0, 0, iGlobalColourBlack, false)
end
iChanX = iChanX + iChannelWidth + 2
end
end
-- Copy to clipboard option selected
if (iGrabThisLineNumber ~= 0) then
local sGrabThisLine = ""
for iStyleKey, sThisStyle in ipairs (sCommsBuffer[iGrabThisLineNumber][3]) do
sGrabThisLine = sGrabThisLine .. sThisStyle.text
end
SetClipboard(sGrabThisLine)
end
-- Calculate scroll bar max sizes, bar position etc.
local iLinesMissing = iCommsMessagesCurrentlyShown - iCommLinesRendered
local iCurrentScrollLine = iCommLineBottomRender - iCommLinesRendered
if (iCurrentScrollLine < 0) then
iCurrentScrollLine = 0
end
-- The scrollbar position indicator
iCommMaxLines = iCommWindowLines + iLinesMissing
if (iCommMaxLines <= iCommWindowLines) then iCommMaxLines = 1 end
SCROLL_BAR_HEIGHT = WINDATA[winComms]["HEIGHT"] - iTopCommsWindow - (2*SCROLL_BAR_WIDTH)
if (not bCommWindowDragScrolling) then
iBarPos = SCROLL_BAR_WIDTH + iTopCommsWindow + ((SCROLL_BAR_HEIGHT/iCommMaxLines) * iCurrentScrollLine)
iBarSize = (SCROLL_BAR_HEIGHT/math.max(iCommWindowLines,iCommMaxLines)) * (iCommWindowLines)
if (iBarSize < 10) then
iBarSize = 10
end
if (iBarPos+iBarSize > SCROLL_BAR_WIDTH+SCROLL_BAR_HEIGHT+iTopCommsWindow) then
iBarPos = SCROLL_BAR_WIDTH+iTopCommsWindow+SCROLL_BAR_HEIGHT - iBarSize
end
WindowMoveHotspot(winComms, "hsCommScroller", (WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH), iBarPos, WINDATA[winComms]["WIDTH"] - 1, iBarPos+iBarSize)
end
DrawThemed3DRect(winComms, WINDATA[winComms]["WIDTH"]-SCROLL_BAR_WIDTH-1, iBarPos, WINDATA[winComms]["WIDTH"]-1, iBarPos+iBarSize)
-- Blank window, display a message
if (iCommsMessagesCurrentlyShown == 0) then
WindowText(winComms, "bodyfont"..winComms, "(no messages to display)", 2, 2 + iTopCommsWindow, 0, 0, iGlobalColourSilver, false)
end
-- Frame the entire window
WindowRectOp(winComms, miniwin.rect_frame, 0, iTopCommsWindow, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
Repaint()
end
-- ***************************************
-- ***** Redraw Shields/Group Window *****
-- ***************************************
function RedrawShieldsWindow()
-- Save effort, do nothing if not showing this window
if (WINDATA[winShields]["SHOW"] == false) then
return
end
WindowRectOp(winShields, miniwin.rect_fill, 0, 0, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], iGlobalColourBlack)
local sUseFont
local iThisLineHeight = iGlobalLineHeight
if (WINDATA[winShields]["WIDTH"] < 250) then
sUseFont = "bodyfont"..winShields
elseif (WINDATA[winShields]["WIDTH"] < 400) then
sUseFont = "bodyfont"..winShields.."m"
iThisLineHeight = iThisLineHeight + 3
else
sUseFont = "bodyfont"..winShields.."l"
iThisLineHeight = iThisLineHeight + 7
end
local iLineCentre = iThisLineHeight / 4
local sUseName = ""
iTotalGroupMembers = 0
local iLongestName = 0
local iCheckWidth = 0
for sCharacter, sGroupData in pairs (sGroupMembers) do
sUseName = ((sCharacter == sMyPlayerName) and "You" or sCharacter)
iTotalGroupMembers = iTotalGroupMembers + 1
iCheckWidth = WindowTextWidth(winShields, sUseFont, sUseName)
if (iCheckWidth > iLongestName) then
iLongestName = iCheckWidth
end
end
if (iLongestName > (WINDATA[winShields]["WIDTH"] * 0.25)) then
iLongestName = math.floor((WINDATA[winShields]["WIDTH"] * 0.25))
end
local bShowTitle = true
local iFreeSpace = WINDATA[winShields]["HEIGHT"]
if (WINDATA[winShields]["HEIGHT"] < ((iTotalGroupMembers + 1) * iThisLineHeight)) then
bShowTitle = false
else
iFreeSpace = iFreeSpace - iThisLineHeight
end
local iPlayerHeight = iFreeSpace / iTotalGroupMembers
if (iPlayerHeight > 30) then
iPlayerHeight = 30
end
if (iThisLineHeight > iPlayerHeight) then
sUseFont = "bodyfont"..winShields
iThisLineHeight = iGlobalLineHeight
iLineCentre = iThisLineHeight / 4
end
local iBarLeft = iLongestName + 5
local iBarTop = 2
local iBarWidth = WINDATA[winShields]["WIDTH"] - iBarLeft - 2
local iBarHeight = iPlayerHeight / 2
local sShieldName = ""
local iHPColour = 0
local iGPColour = 0
local iThisFontWidth = WindowTextWidth(winShields, sUseFont, "CCC")
local iShieldTypeWidth = (iBarWidth - iThisFontWidth) / 4
local iThisShieldColour = 0
local iThisBackColour = 0
local iTextTopAdd = iBarHeight - (iThisLineHeight / 2)
if (bShowTitle == true) then
if (iTotalGroupMembers > 1) then
WindowText(winShields, sUseFont, "Group Members: " .. (iTotalGroupMembers - 1), iBarLeft + 3, 1, 0, 0, iGlobalColourSilver, false)
else
WindowText(winShields, sUseFont, "No Group Detected", iBarLeft + 3, 1, 0, 0, iGlobalColourSilver, false)
end
iBarTop = iBarTop + iThisLineHeight + 1
end
iTotalGroupMembers = iTotalGroupMembers - 1
for sCharacter, sGroupData in pairs (sGroupMembers) do
if (iTotalGroupMembers == 0 or sCharacter ~= "You") then
-- Switch to our own character data if this group member is known to be "me"
sUseName = ((sCharacter == sMyPlayerName) and "You" or sCharacter)
-- Get the colours of the bars to apply
iHPColour = PercentageToColour(sGroupMembers[sUseName]["HP"], sUSER_OPTIONS["vitals_hp_a"], sUSER_OPTIONS["vitals_hp_b"], sUSER_OPTIONS["vitals_hp_c"])
iGPColour = PercentageToColour(sGroupMembers[sUseName]["GP"], sUSER_OPTIONS["vitals_gp_a"], sUSER_OPTIONS["vitals_gp_b"], sUSER_OPTIONS["vitals_gp_c"])
-- Draw the playername
WindowText(winShields, sUseFont, ((sCharacter == sMyPlayerName) and "You" or sCharacter), 2, iBarTop + iTextTopAdd, 0, 0, iGlobalColourSilver, false)
-- Draw the HP bars
WindowRectOp(winShields, miniwin.rect_fill, iBarLeft, iBarTop, iBarLeft+math.floor((sGroupMembers[sUseName]["HP"] / 100) * iBarWidth), iBarTop + iBarHeight, iHPColour)
-- Draw the GP bars
WindowRectOp(winShields, miniwin.rect_fill, iBarLeft, iBarTop + iBarHeight, iBarLeft+math.floor((sGroupMembers[sUseName]["GP"] / 100) * iBarWidth), iBarTop + iPlayerHeight, iGPColour)
-- Box them in
WindowRectOp(winShields, miniwin.rect_frame, iBarLeft, iBarTop, iBarLeft+iBarWidth, iBarTop+iPlayerHeight, iGlobalColourSilver, iGlobalColourBlack)
-- Text for shield notices/statuses
for sShieldType, iShieldStatus in pairs(sGroupMembers[sUseName]) do
if (iShieldStatus == 0) then
iThisBackColour = 0
iThisShieldColour = 0
else
iThisBackColour = 0
iThisShieldColour = iGlobalColourSilver
end
if (iThisFontWidth > iShieldTypeWidth) then
sShieldName = string.sub(sShieldType, 1, 1)
else
sShieldName = sShieldType
end
if (sShieldType == "TPA") then
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 2, iBarTop - 1 + iTextTopAdd, 0, 0, iThisBackColour, false)
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 3, iBarTop + iTextTopAdd, 0, 0, iThisShieldColour, false)
elseif (sShieldType == "CCC") then
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 2 + (iShieldTypeWidth), iBarTop - 1 + iTextTopAdd, 0, 0, iThisBackColour, false)
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 3 + (iShieldTypeWidth), iBarTop + iTextTopAdd, 0, 0, iThisShieldColour, false)
elseif (sShieldType == "EFF") then
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 2 + (iShieldTypeWidth * 2), iBarTop - 1 + iTextTopAdd, 0, 0, iThisBackColour, false)
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 3 + (iShieldTypeWidth * 2), iBarTop + iTextTopAdd, 0, 0, iThisShieldColour, false)
elseif (sShieldType == "KII") then
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 2 + (iShieldTypeWidth * 3), iBarTop - 1 + iTextTopAdd, 0, 0, iThisBackColour, false)
WindowText(winShields, sUseFont, sShieldName, iBarLeft + 3 + (iShieldTypeWidth * 3), iBarTop + iTextTopAdd, 0, 0, iThisShieldColour, false)
elseif (sShieldType == "MS") then
WindowText(winShields, sUseFont, sShieldName, (iBarLeft + iBarWidth) - iThisFontWidth, iBarTop - 1 + iTextTopAdd, 0, 0, iThisBackColour, false)
WindowText(winShields, sUseFont, sShieldName, (iBarLeft + iBarWidth) - iThisFontWidth, iBarTop + iTextTopAdd, 0, 0, iThisShieldColour, false)
end
end
end
iBarTop = iBarTop + iPlayerHeight + 1
end
WindowRectOp(winShields, miniwin.rect_frame, 0, 0, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
end
-- ****************************************
-- ***** XP Rates and XP Graph Window *****
-- ****************************************
-- **********************************************
-- ***** Each Minute, Record Last Minute XP *****
-- **********************************************
function UpdateXPGraph()
-- Don't add to minutes if we haven't seen an XP count yet, or aren't currently connected to the mud
if (iXPTotalMinutePrevious == nil or iCharVitals["xp"] == 0 or GetInfo(106) ~= false) then
return
end
-- Get the XP difference since previous minute
if (iXPTotalMinuteCurrent == nil) then
iXPTotalMinuteCurrent = iCharVitals["xp"]
end
iXPTotalMinutePrevious = iXPTotalMinuteCurrent
iXPTotalMinuteCurrent = iCharVitals["xp"]
local iXPThisMinute = (iXPTotalMinuteCurrent - iXPTotalMinutePrevious)
if (iXPThisMinute < 0) then
iXPThisMinute = 0
end
-- Delete the oldest XP point if we have 60
if (#iXPGraphPlots == 60) then
table.remove(iXPGraphPlots, 1)
table.remove(iXPTotalPlots, 1)
end
-- Add this last minute's XP to the xp-each-minute table
iXPTotalPlots[#iXPTotalPlots + 1] = iXPThisMinute
-- Work out the new hourly rate
iXPPastHour = 0
iXPHighestPlot = 0
for iN = 1, #iXPTotalPlots do
iXPPastHour = iXPPastHour + iXPTotalPlots[iN]
if (iN < #iXPTotalPlots and iXPGraphPlots[iN] > iXPHighestPlot) then
iXPHighestPlot = iXPGraphPlots[iN]
end
end
-- Divide the past "hour" (or less) worth of XP by the number of minutes measured
if (#iXPGraphPlots > 0) then
iXPPerHour = math.floor((iXPPastHour / #iXPTotalPlots) * 60)
else
iXPPerHour = 0
end
-- Add the current point to the table
iXPGraphPlots[#iXPGraphPlots + 1] = (iXPPerHour < 1000001) and iXPPerHour or 1000000
-- Check if it's a new high-point
if (iXPPerHour > iXPHighestPlot) then
iXPHighestPlot = iXPPerHour
end
-- *TOTAL* xp and minutes since recording
iXPTotalRecordedIncoming = iXPTotalRecordedIncoming + iXPThisMinute
iXPMinutesRecordedTotal = iXPMinutesRecordedTotal + 1
-- Now finally redraw the chart
RedrawXPWindow(true)
end
-- ***********************************
-- ***** HP and XP Notices Queue *****
-- ***********************************
sTextNoticesQueue = {}
function QuowDisplayNotices()
for iKey, sData in ipairs(sTextNoticesQueue) do
if (sData[1] == 1) then
-- HP Notice
ColourTell("#C0C0C0", "black", "{")
ColourTell("red", "black", tostring(sData[2]))
ColourNote("#C0C0C0", "black", "} ")
elseif (sData[1] == 2) then
-- XP Notice
ColourTell("#C0C0C0", "black", "{")
ColourTell("cyan", "black", tostring(sData[2]))
ColourNote("#C0C0C0", "black", "} ")
end
end
sTextNoticesQueue = {}
end
-- ********************************************
-- ***** Redraw XP Graph Plottings/Window *****
-- ********************************************
function RedrawXPWindow(bRedrawGraph)
-- Save effort, do nothing if not showing this window
if (WINDATA[winXP]["SHOW"] == false) then
return
end
local iKeyColour = iGlobalColourSilver
local iY = 2
local sUseFont
local iThisLineHeight = iGlobalLineHeight
local iGraphTop = iThisLineHeight + 8
if (WINDATA[winXP]["WIDTH"] < 250) then
sUseFont = "bodyfont"..winXP
elseif (WINDATA[winXP]["WIDTH"] < 400) then
sUseFont = "bodyfont"..winXP.."m"
iThisLineHeight = iThisLineHeight + 2
iGraphTop = iThisLineHeight + 11
else
sUseFont = "bodyfont"..winXP.."l"
iThisLineHeight = iThisLineHeight + 6
iGraphTop = iThisLineHeight + 12
end
-- Blank the top part of the window
if (bRedrawGraph ~= nil) then
WindowRectOp(winXP, miniwin.rect_fill, 0, 0, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], iGlobalColourBlack)
else
WindowRectOp(winXP, miniwin.rect_fill, 0, 0, WINDATA[winXP]["WIDTH"], (iThisLineHeight * 3) + 2, iGlobalColourBlack)
end
WindowText(winXP, sUseFont, NumberCommaString(iCharVitals["xp"]) .. " xp", 5, iY, 0, 0, iKeyColour, false)
iY = iY + iThisLineHeight
WindowText(winXP, sUseFont, NumberCommaString(iXPTotalRecordedIncoming) .. " xp gained in", 5, iY, 0, 0, iKeyColour, false)
iY = iY + iThisLineHeight
WindowText(winXP, sUseFont, MinutesToTimeString(iXPMinutesRecordedTotal) .. " " .. ((#iXPGraphPlots > 1) and NumberCommaString(iXPPerHour) .. " xp/h" or "(wait for reliable xp/h)"), 5, iY, 0, 0, iKeyColour, false)
-- Don't re-do the XP graph?
if (bRedrawGraph == nil) then
-- Frame the window before exiting this function
WindowRectOp(winXP, miniwin.rect_frame, 0, 0, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
return
end
iGraphTop = iGraphTop + iY
local iGraphHeight = WINDATA[winXP]["HEIGHT"] - (iGraphTop + 3)
-- Save the effort, don't do all the plotting if there's not enough room!
if (iGraphHeight < 50) then
-- Frame the window before exiting this function
WindowRectOp(winXP, miniwin.rect_frame, 0, 0, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
return
end
local iThisFontWidth = WindowTextWidth(winXP, sUseFont, "1000k")
local iGraphLeft = iThisFontWidth + 2
if (iXPHighestPlot > 900000) then
iXPHighestPlot = 900000
end
local iHighPlotPoint = (math.floor(iXPHighestPlot / 100000) + 1) * 100000
local iValuePerSpace = math.floor(iHighPlotPoint / 5)
local iPlot1 = math.floor((iHighPlotPoint) / 1000)
local iPlot2 = math.floor((iHighPlotPoint - iValuePerSpace) / 1000)
local iPlot3 = math.floor((iHighPlotPoint - (iValuePerSpace * 2)) / 1000)
local iPlot4 = math.floor((iHighPlotPoint - (iValuePerSpace * 3)) / 1000)
local iPlot5 = math.floor((iHighPlotPoint - (iValuePerSpace * 4)) / 1000)
local sPlot1 = ((iPlot1 < 1000) and iPlot1 .. "k" or "1m")
local sPlot2 = iPlot2 .. "k"
local sPlot3 = iPlot3 .. "k"
local sPlot4 = iPlot4 .. "k"
local sPlot5 = iPlot5 .. "k"
local iGraphChunk = math.floor(iGraphHeight / 5)
local iGraphWidth = WINDATA[winXP]["WIDTH"] - (iGraphLeft + 5)
-- Graph borders
WindowLine (winXP, iGraphLeft, iGraphTop, iGraphLeft, iGraphTop + iGraphHeight, iKeyColour, 0, 2)
WindowLine (winXP, iGraphLeft, iGraphTop + iGraphHeight, iGraphLeft + iGraphWidth, iGraphTop + iGraphHeight, iKeyColour, 0, 2)
-- Graph scale lines
WindowLine (winXP, iGraphLeft, iGraphTop, iGraphLeft + iGraphWidth, iGraphTop, iKeyColour, 2, 1)
WindowLine (winXP, iGraphLeft, iGraphTop + (iGraphChunk), iGraphLeft + iGraphWidth, iGraphTop + (iGraphChunk), iKeyColour, 2, 1)
WindowLine (winXP, iGraphLeft, iGraphTop + (iGraphChunk * 2), iGraphLeft + iGraphWidth, iGraphTop + (iGraphChunk * 2), iKeyColour, 2, 1)
WindowLine (winXP, iGraphLeft, iGraphTop + (iGraphChunk * 3), iGraphLeft + iGraphWidth, iGraphTop + (iGraphChunk * 3), iKeyColour, 2, 1)
WindowLine (winXP, iGraphLeft, iGraphTop + (iGraphChunk * 4), iGraphLeft + iGraphWidth, iGraphTop + (iGraphChunk * 4), iKeyColour, 2, 1)
-- Graph key
WindowText (winXP, "bodyfont"..winXP, sPlot1, 2, iGraphTop - (iThisLineHeight / 2), 0, 0, iKeyColour, false)
WindowText (winXP, "bodyfont"..winXP, sPlot2, 2, (iGraphTop + iGraphChunk) - (iThisLineHeight / 2), 0, 0, iKeyColour, false)
WindowText (winXP, "bodyfont"..winXP, sPlot3, 2, (iGraphTop + (iGraphChunk * 2)) - (iThisLineHeight / 2), 0, 0, iKeyColour, false)
WindowText (winXP, "bodyfont"..winXP, sPlot4, 2, (iGraphTop + (iGraphChunk * 3)) - (iThisLineHeight / 2), 0, 0, iKeyColour, false)
WindowText (winXP, "bodyfont"..winXP, sPlot5, 2, (iGraphTop + (iGraphChunk * 4)) - (iThisLineHeight / 2), 0, 0, iKeyColour, false)
if (#iXPGraphPlots > 1) then
local iPlotWidth = (iGraphWidth / (#iXPGraphPlots - 1))
local iGX = iGraphLeft + 1
local iGY = iGraphTop + ((1 - (iXPGraphPlots[1] / iHighPlotPoint)) * iGraphHeight)
local iGYNext
for iN = 2, #iXPGraphPlots do
iGYNext = iGraphTop + ((1 - (iXPGraphPlots[iN] / iHighPlotPoint)) * iGraphHeight)
WindowLine (winXP, iGX, iGY, iGX + iPlotWidth, iGYNext, ColourNameToRGB ("green"), 0, 2)
iGX = iGX + iPlotWidth
iGY = iGYNext
end
end
-- Frame the window
WindowRectOp(winXP, miniwin.rect_frame, 0, 0, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
end
-- ****************************************
-- ***** Character bars data handling *****
-- ****************************************
function RedrawVitalsWindow()
-- Save effort, do nothing if not showing this window
if (WINDATA[winBars]["SHOW"] == false) then
return
end
-- Clear the window afresh and draw a new border
WindowRectOp(winBars, miniwin.rect_fill, 0, 0, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], iGlobalColourBlack)
local iDifference = 0
-- We have a changed *MAX* HP, but an unchanged HP, correct the values so we don't treat it as a real "drop"
if (iCharOldVitals["maxhp"] ~= iCharVitals["maxhp"] and iCharOldVitals["maxhp"] == iCharVitals["hp"]) then
iDifference = iCharOldVitals["maxhp"] - iCharOldVitals["maxhp"]
if (iDifference > 0) then
iCharVitals["hp"] = iCharVitals["maxhp"] - iDifference
iCharOldVitals["maxhp"] = iCharVitals["hp"]
iCharOldVitals["maxhp"] = iCharVitals["maxhp"]
end
end
-- We have a changed *MAX* GP, but an unchanged GP
if (iCharOldVitals["maxgp"] ~= iCharVitals["maxgp"] and iCharOldVitals["gp"] == iCharVitals["gp"]) then
iDifference = iCharOldVitals["maxgp"] - iCharOldVitals["gp"]
if (iDifference > 0) then
iCharVitals["gp"] = iCharVitals["maxgp"] - iDifference
iCharOldVitals["gp"] = iCharVitals["gp"]
iCharOldVitals["maxgp"] = iCharVitals["maxgp"]
end
end
local iHPPercentage = iCharVitals["maxhp"] > 0 and math.floor(iCharVitals["hp"] / iCharVitals["maxhp"] * 100) or 0
local iGPPercentage = iCharVitals["maxgp"] > 0 and math.floor(iCharVitals["gp"] / iCharVitals["maxgp"] * 100) or 0
local iBurdenPercentage = iCharVitals["burden"]
if (iGPPercentage < 75 and iGPPercentage ~= 0) then
bGPThresholdMet = true
elseif (iGPPercentage == 100) then
if (bPlayGPNotification == true and bGPThresholdMet == true) then
PlaySound (1, sGPNotificationFile, false, -10, 0)
end
bGPThresholdMet = false
end
if (iHPPercentage ~= sGroupMembers["You"]["HP"] or iGPPercentage ~= sGroupMembers["You"]["GP"]) then
sGroupMembers["You"]["HP"] = iHPPercentage
sGroupMembers["You"]["GP"] = iGPPercentage
RedrawShieldsWindow()
end
-- Pre-calculate the colours
local iHPColour = PercentageToColour(iHPPercentage, sUSER_OPTIONS["vitals_hp_a"], sUSER_OPTIONS["vitals_hp_b"], sUSER_OPTIONS["vitals_hp_c"])
local iGPColour = PercentageToColour(iGPPercentage, sUSER_OPTIONS["vitals_gp_a"], sUSER_OPTIONS["vitals_gp_b"], sUSER_OPTIONS["vitals_gp_c"])
local iBurdenColour = PercentageToColour(100-iBurdenPercentage, sUSER_OPTIONS["vitals_b_a"], sUSER_OPTIONS["vitals_b_b"], sUSER_OPTIONS["vitals_b_c"])
local iBarsHeight, iKeyWidth, iBarWidth, iCentreFontHeight, sUseFont
if (bVitalStacking == true) then
-- Calculate the bar heights, widths, and locations based on the window size
iBarsHeight = math.floor(WINDATA[winBars]["HEIGHT"] / 3) - 3
local iHPBarTop = 3
local iGPBarTop = math.floor((WINDATA[winBars]["HEIGHT"] - iBarsHeight) / 2)
local iBurdenBarTop = WINDATA[winBars]["HEIGHT"] - (3+iBarsHeight)
iCentreFontHeight = math.floor((iBarsHeight - iGlobalLineHeight) / 2)
if (iBarsHeight < 30) then
sUseFont = "bodyfont"..winBars
elseif (iBarsHeight < 60) then
sUseFont = "bodyfont"..winBars.."m"
else
sUseFont = "bodyfont"..winBars.."l"
end
-- Get the width of the left-bar-text
iKeyWidth = WindowTextWidth (winBars, sUseFont, "GP")
local iBarLeft = iKeyWidth + 10
iBarWidth = WINDATA[winBars]["WIDTH"] - (iBarLeft + 3)
-- Draw the texts to the left of the bars
WindowText(winBars, sUseFont, "HP", 3, iHPBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "GP", 3, iGPBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "B", 3, iBurdenBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
-- Draw the HP bars
WindowGradient (winBars, iBarLeft, iHPBarTop, iBarLeft+math.floor((iHPPercentage / 100) * iBarWidth), iHPBarTop + (iBarsHeight / 2), 0x000000, iHPColour, 2)
WindowGradient (winBars, iBarLeft, iHPBarTop + (iBarsHeight / 2), iBarLeft+math.floor((iHPPercentage / 100) * iBarWidth), iHPBarTop + iBarsHeight, iHPColour, 0x000000, 2)
WindowRectOp(winBars, miniwin.rect_frame, iBarLeft, iHPBarTop, iBarLeft+iBarWidth, iHPBarTop+iBarsHeight, iGlobalColourSilver, iGlobalColourBlack)
-- Draw the GP bars
WindowGradient (winBars, iBarLeft, iGPBarTop, iBarLeft+math.floor((iGPPercentage / 100) * iBarWidth), iGPBarTop + (iBarsHeight / 2), 0x000000, iGPColour, 2)
WindowGradient (winBars, iBarLeft, iGPBarTop + (iBarsHeight / 2), iBarLeft+math.floor((iGPPercentage / 100) * iBarWidth), iGPBarTop + iBarsHeight, iGPColour, 0x000000, 2)
WindowRectOp(winBars, miniwin.rect_frame, iBarLeft, iGPBarTop, iBarLeft+iBarWidth, iGPBarTop+iBarsHeight, iGlobalColourSilver, iGlobalColourBlack)
-- Draw the burden bars
WindowGradient (winBars, iBarLeft, iBurdenBarTop, iBarLeft+math.floor((iBurdenPercentage / 100) * iBarWidth), iBurdenBarTop + (iBarsHeight / 2), 0x000000, iBurdenColour, 2)
WindowGradient (winBars, iBarLeft, iBurdenBarTop + (iBarsHeight / 2), iBarLeft+math.floor((iBurdenPercentage / 100) * iBarWidth), iBurdenBarTop + iBarsHeight, iBurdenColour, 0x000000, 2)
WindowRectOp(winBars, miniwin.rect_frame, iBarLeft, iBurdenBarTop, iBarLeft+iBarWidth, iBurdenBarTop+iBarsHeight, iGlobalColourSilver, iGlobalColourBlack)
-- Draw the text overlays twice each (once for a faux-shadow)
if (iCharVitals["maxhp"] == -1) then
WindowText(winBars, sUseFont, "Not yet set", iBarLeft + 4, iHPBarTop + iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, "Not yet set", iBarLeft + 5, iHPBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "Not yet set", iBarLeft + 4, iGPBarTop + iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, "Not yet set", iBarLeft + 5, iGPBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "Not yet set", iBarLeft + 4, iBurdenBarTop + iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, "Not yet set", iBarLeft + 5, iBurdenBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
else
WindowText(winBars, sUseFont, iCharVitals["hp"] .. " / " .. iCharVitals["maxhp"], iBarLeft + 4, iHPBarTop + iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, iCharVitals["hp"] .. " / " .. iCharVitals["maxhp"], iBarLeft + 5, iHPBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, iCharVitals["gp"] .. " / " .. iCharVitals["maxgp"], iBarLeft + 4, iGPBarTop + iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, iCharVitals["gp"] .. " / " .. iCharVitals["maxgp"], iBarLeft + 5, iGPBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, iCharVitals["burden"] .. " %", iBarLeft + 4, iBurdenBarTop + iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, iCharVitals["burden"] .. " %", iBarLeft + 5, iBurdenBarTop + iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
end
else
iBarsHeight = WINDATA[winBars]["HEIGHT"] - 4
if (iBarsHeight < 30 or WINDATA[winBars]["WIDTH"] < 400) then
sUseFont = "bodyfont"..winBars
elseif (iBarsHeight < 60) then
sUseFont = "bodyfont"..winBars.."m"
else
sUseFont = "bodyfont"..winBars.."l"
end
-- Get the width of the left-bar-text
iKeyWidth = WindowTextWidth (winBars, sUseFont, "GP")
iBarWidth = math.floor((WINDATA[winBars]["WIDTH"] - (iKeyWidth * 3)) / 3) - 3
local iHPBarLeft = iKeyWidth + 3
local iGPBarLeft = iHPBarLeft + iBarWidth + iKeyWidth + 3
local iBurdenBarLeft = iGPBarLeft + iBarWidth + iKeyWidth + 3
local iCentreFontLeft = 0
iCentreFontHeight = 2 + math.floor((iBarsHeight - iGlobalLineHeight) / 2)
-- Draw the texts to the left of the bars
WindowText(winBars, sUseFont, "HP", 2, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "GP", iGPBarLeft - iKeyWidth, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "B", iBurdenBarLeft - iKeyWidth, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
-- Draw the HP bars
WindowGradient (winBars, iHPBarLeft, 2, iHPBarLeft+math.floor((iHPPercentage / 100) * iBarWidth), 2 + (iBarsHeight / 2), 0x000000, iHPColour, 2)
WindowGradient (winBars, iHPBarLeft, 2 + (iBarsHeight / 2), iHPBarLeft+math.floor((iHPPercentage / 100) * iBarWidth), 2 + iBarsHeight, iHPColour, 0x000000, 2)
WindowRectOp(winBars, miniwin.rect_frame, iHPBarLeft, 2, iHPBarLeft+iBarWidth, 2+iBarsHeight, iGlobalColourSilver, iGlobalColourBlack)
-- Draw the GP bars
WindowGradient (winBars, iGPBarLeft, 2, iGPBarLeft+math.floor((iGPPercentage / 100) * iBarWidth), 2 + (iBarsHeight / 2), 0x000000, iGPColour, 2)
WindowGradient (winBars, iGPBarLeft, 2 + (iBarsHeight / 2), iGPBarLeft+math.floor((iGPPercentage / 100) * iBarWidth), 2 + iBarsHeight, iGPColour, 0x000000, 2)
WindowRectOp(winBars, miniwin.rect_frame, iGPBarLeft, 2, iGPBarLeft+iBarWidth, 2+iBarsHeight, iGlobalColourSilver, iGlobalColourBlack)
-- Draw the burden bars
WindowGradient (winBars, iBurdenBarLeft, 2, iBurdenBarLeft+math.floor((iBurdenPercentage / 100) * iBarWidth), 2 + (iBarsHeight / 2), 0x000000, iBurdenColour, 2)
WindowGradient (winBars, iBurdenBarLeft, 2 + (iBarsHeight / 2), iBurdenBarLeft+math.floor((iBurdenPercentage / 100) * iBarWidth), 2 + iBarsHeight, iBurdenColour, 0x000000, 2)
WindowRectOp(winBars, miniwin.rect_frame, iBurdenBarLeft, 2, iBurdenBarLeft+iBarWidth, 2+iBarsHeight, iGlobalColourSilver, iGlobalColourBlack)
-- Draw the text overlays twice each (once for a faux-shadow)
if (iCharVitals["maxhp"] == -1) then
WindowText(winBars, sUseFont, "Not set", iHPBarLeft + 4, iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, "Not set", iHPBarLeft + 5, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "Not set", iGPBarLeft + 4, iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, "Not set", iGPBarLeft + 5, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, "Not set", iBurdenBarLeft + 4, iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, "Not set", iBurdenBarLeft + 5, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
else
WindowText(winBars, sUseFont, iCharVitals["hp"] .. " / " .. iCharVitals["maxhp"], iHPBarLeft + 4, iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, iCharVitals["hp"] .. " / " .. iCharVitals["maxhp"], iHPBarLeft + 5, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, iCharVitals["gp"] .. " / " .. iCharVitals["maxgp"], iGPBarLeft + 4, iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, iCharVitals["gp"] .. " / " .. iCharVitals["maxgp"], iGPBarLeft + 5, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
WindowText(winBars, sUseFont, iCharVitals["burden"] .. " %", iBurdenBarLeft + 4, iCentreFontHeight - 1, 0, 0, iGlobalColourBlack, false)
WindowText(winBars, sUseFont, iCharVitals["burden"] .. " %", iBurdenBarLeft + 5, iCentreFontHeight, 0, 0, iGlobalColourSilver, false)
end
end
-- Border the whole window
WindowRectOp(winBars, miniwin.rect_frame, 0, 0, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
end
-- ****************************************
-- ***** Colour Phasing by Percentage *****
-- ****************************************
-- Gradiate a colour through three possibilities
function PercentageToColour(iPerc, iHigh, iMed, iLow)
-- Convert the 0-100 percentage, to a range of -1 through to +1
local iRange = (math.min(math.max(0, iPerc), 100) - 50) / 50
-- Convert the RGB into hex so we can split off the three channels
local sHighHex = string.format("%06X", iHigh)
local sMedHex = string.format("%06X", iMed)
local sLowHex = string.format("%06X", iLow)
-- Convert hex back to decimal, now cutting into the three RGB channels, for the three provided colours
local iHighR = tonumber(string.sub(sHighHex, 5, 6), 16)
local iHighG = tonumber(string.sub(sHighHex, 3, 4), 16)
local iHighB = tonumber(string.sub(sHighHex, 1, 2), 16)
local iMedR = tonumber(string.sub(sMedHex, 5, 6), 16)
local iMedG = tonumber(string.sub(sMedHex, 3, 4), 16)
local iMedB = tonumber(string.sub(sMedHex, 1, 2), 16)
local iLowR = tonumber(string.sub(sLowHex, 5, 6), 16)
local iLowG = tonumber(string.sub(sLowHex, 3, 4), 16)
local iLowB = tonumber(string.sub(sLowHex, 1, 2), 16)
-- Now apply the range to each of those three channels for all three colours passed in, weighted from high through to low
local iColR = math.ceil((iHighR * math.max(0, iRange)) + (iMedR * (1 - math.abs(iRange))) + (iLowR * math.max(0, -iRange)))
local iColG = math.ceil((iHighG * math.max(0, iRange)) + (iMedG * (1 - math.abs(iRange))) + (iLowG * math.max(0, -iRange)))
local iColB = math.ceil((iHighB * math.max(0, iRange)) + (iMedB * (1 - math.abs(iRange))) + (iLowB * math.max(0, -iRange)))
-- Return the final sum in RGB form
return (iColR + (iColG * 256) + (iColB * 65536))
end
-- ****************************************
-- ***** String And Styles into Table *****
-- ****************************************
-- Converts a large bit of string sent by the mud, including raw MXP codes, into a table of words with style colours
local function StringToStyleTable(sLineText)
local sWordsTable, iHere, sThisColour, sSplitWord, iFound = {}, 1, sGlobalColourSilver, "", sLineText:find("(%s+)()(%S+)()")
if iFound then
sWordsTable[1] = {string.sub(sLineText, 1, iFound-1), sThisColour}
else
return {sLineText, sThisColour}
end
sLineText:gsub("(%s+)()(%S+)()",
function(sp, st, sWord, fi)
-- Look for the START of a new colour-style MXP code
if (string.sub(sWord, 1, 13) == "\\u001b[4zMXP<") then
iHere = string.find(sWord, "MXP>")
sThisColour = string.sub(sWord, 14, iHere - 1)
if (string.sub(sThisColour, 1, 2) == "C ") then
sThisColour = string.sub(sThisColour, 3)
end
sWord = string.sub(sWord, iHere + 4)
-- Could be 2 colour-codes because of PK colour options
if (string.sub(sWord, 1, 13) == "\\u001b[4zMXP<") then
iHere = string.find(sWord, "MXP>")
sThisColour = string.sub(sWord, 14, iHere - 1)
if (string.sub(sThisColour, 1, 2) == "C ") then
sThisColour = string.sub(sThisColour, 3)
end
sWord = string.sub(sWord, iHere + 4)
end
end
-- Check for the code to STOP colour-styles now
iHere = string.find(sWord, "\\u001b%[3z")
if (iHere ~= nil) then
sSplitWord = string.sub(sWord, 1, iHere - 1)
sWordsTable[#sWordsTable + 1] = {" " .. sSplitWord, sThisColour}
sThisColour = sGlobalColourSilver
sWord = string.sub(sWord, iHere + 9)
sWordsTable[#sWordsTable + 1] = {sWord, sThisColour}
else
sWordsTable[#sWordsTable + 1] = {" " .. sWord, sThisColour}
end
end)
return sWordsTable
end
-- *************************************
-- ***** MapDoorText data handling *****
-- *************************************
-- Tables for storing MapDoorText
sLastFullMDT = ""
iEnemiesBySquare = {}
objEntityTable = {}
iTotalMDTLines = 0
iLongestMDTDir = 0
iMDTRoomsIgnored = 0
iMDTMinimumRoomValue = 0
function RedrawMDTWindow()
-- Save effort, do nothing if not showing this window
if (WINDATA[winMDT]["SHOW"] == false) then
return
end
local bDoneHere = false
local sTempText = ""
-- Clear the window afresh and draw a new border
WindowRectOp(winMDT, miniwin.rect_fill, 0, 0, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], iGlobalColourBlack)
local iMDTTextX = 1
local iMDTTextY = WINDATA[winMDT]["HEIGHT"] - (iGlobalLineHeight + 1)
if (sLastFullMDT ~= "") then
-- "Raw" map door text, no MDT plugin detected, convert the raw text and the MXP colour codes and word-wrap it to the window
local iTX, iTY, iAddWidth = 1, 1, 0
local iLettersPerLine = (WINDATA[winMDT]["WIDTH"] / iGlobalFontWidth) - 2
sLastFullMDT = string.gsub(sLastFullMDT, "\\u001b%[4zMXP<C ", "\\u001b%[4zMXP<")
for iWordCount, sWordText in pairs(StringToStyleTable(sLastFullMDT)) do
-- Loop through the individual words, with newly created style info
if (sWordText[1] ~= nil) then
iAddWidth = WindowTextWidth(winMDT, "bodyfont"..winMDT, sWordText[1])
if ((iTX + iAddWidth) > WINDATA[winMDT]["WIDTH"]) then
-- This word was take us over the edge, so put it onto the next line
iTX = 1
iTY = iTY + iGlobalLineHeight
-- No point starting a new line with a space, so remove leading spaces from this first line word!
if (string.sub(sWordText[1], 1, 1) == " ") then
iAddWidth = iAddWidth - iGlobalFontWidth
sWordText[1] = string.sub(sWordText[1], 2)
end
end
-- Draw the text to the window with the relevant colour code
WindowText(winMDT, "bodyfont"..winMDT, sWordText[1], iTX, iTY, 0, 0, ColourNameToRGB(sWordText[2]), false)
iTX = iTX + iAddWidth
end
end
else
-- Fully parsed MDT redrawing
for iKey, sValue in pairs (iEnemiesBySquare) do
-- Only show if this room has at least "iMDTMinimumRoomValue" value and it's within window limit
if (sValue[4] >= iMDTMinimumRoomValue) then
bDoneHere = false
iMDTTextX = iMDTTextX + WindowText(winMDT, "bodyfont"..winMDT, string.format("%-" .. iLongestMDTDir .. "s ", sValue[2]) .. "[", iMDTTextX, iMDTTextY, 0, 0, iGlobalColourSilver, false)
iMDTTextX = iMDTTextX + WindowText(winMDT, "bodyfont"..winMDT, sValue[4], iMDTTextX, iMDTTextY, 0, 0, iGlobalColourOrange, false)
iMDTTextX = iMDTTextX + WindowText(winMDT, "bodyfont"..winMDT, "] ", iMDTTextX, iMDTTextY, 0, 0, iGlobalColourSilver, false)
for sTKey, objEntity in pairs(objEntityTable) do
if (objEntity[1] == sValue[3] and objEntity[3] ~= "") then
sTempText = objEntity[2]
if (bDoneHere == true) then
sTempText = ", " .. sTempText
end
iMDTTextX = iMDTTextX + WindowText(winMDT, "bodyfont"..winMDT, sTempText, iMDTTextX, iMDTTextY, 0, 0, ColourNameToRGB(objEntity[3]), false)
bDoneHere = true
end
end
for sTKey, objEntity in pairs(objEntityTable) do
if (objEntity[1] == sValue[3] and objEntity[3] == "") then
sTempText = objEntity[2]
if (bDoneHere == true) then
sTempText = ", " .. sTempText
end
iMDTTextX = iMDTTextX + WindowText(winMDT, "bodyfont"..winMDT, sTempText, iMDTTextX, iMDTTextY, 0, 0, iGlobalColourSilver, false)
bDoneHere = true
end
end
iMDTTextX = 1
iMDTTextY = iMDTTextY - (iGlobalLineHeight + 1)
end
if (iMDTTextY < -iGlobalLineHeight) then
break
end
end
if (iMDTRoomsIgnored > 0 and iMDTTextY > winThemeData.TITLE_HEIGHT) then
sTempText = "(" .. tostring(iMDTRoomsIgnored) .. " room"
if (iMDTRoomsIgnored > 1) then
sTempText = sTempText .. "s"
end
sTempText = sTempText .. " below your value limit of " .. tostring(iMDTMinimumRoomValue) .. ")"
WindowText(winMDT, "bodyfont"..winMDT, sTempText, iMDTTextX, iMDTTextY, 0, 0, iGlobalColourSilver, false)
end
if (iTotalMDTLines == 0 and iMDTRoomsIgnored == 0) then
WindowText(winMDT, "bodyfont"..winMDT, "(nothing nearby)", 2, 2, 0, 0, iGlobalColourSilver, false)
end
end
-- Border the whole window
WindowRectOp(winMDT, miniwin.rect_frame, 0, 0, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], iGlobalColourSilver, iGlobalColourBlack)
end
-- Ask the user for a new colour selection, store it, update triggers, display samples etc.
function FetchTriggerColour(sColourOption)
iNewColour = PickColour(ColourNameToRGB(sUSER_OPTIONS[sColourOption]))
if (iNewColour ~= -1) then
sUSER_OPTIONS[sColourOption] = RGBColourToName(iNewColour)
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. EscapeSQL(sUSER_OPTIONS[sColourOption]) .. "' WHERE option_id='" .. sColourOption .. "'"))
ColourNote(sUSER_OPTIONS[sColourOption], "", sRMBResult .. " sample A: Colour is now changed to '" .. sUSER_OPTIONS[sColourOption] .. "'.")
ColourNote(sUSER_OPTIONS[sColourOption], "", sRMBResult .. " sample B: Colour is now changed to '" .. sUSER_OPTIONS[sColourOption] .. "'.")
-- Have to use call plugin for this, as trigger data isn't plugin-specific in right-click menus for some reason!
CallPlugin ("bfe35205f026786ea1d56e3b", "TriggersRecolour", "", "")
else
ColourNote(sUSER_OPTIONS[sColourOption], "", sRMBResult .. " sample A: Colour unchanged from '" .. sUSER_OPTIONS[sColourOption] .. "'.")
ColourNote(sUSER_OPTIONS[sColourOption], "", sRMBResult .. " sample B: Colour unchanged from '" .. sUSER_OPTIONS[sColourOption] .. "'.")
end
end
function FetchVitalsColour(iCurrentColour, sOptionName)
iNewColour = PickColour(iCurrentColour)
if (iNewColour ~= -1) then
sUSER_OPTIONS[sOptionName] = iNewColour
assert(dbUserData:execute("UPDATE user_options SET option_value=" .. sUSER_OPTIONS[sOptionName] .. " WHERE option_id='" .. sOptionName .. "'"))
-- Redraw the vitals properly
CallPlugin ("bfe35205f026786ea1d56e3b", "RedrawVitalsWindow", "", "")
Repaint()
end
end
-- MiniWindow variables
movewindow = {} -- table to hold functions like movewindow.install
-- make a mouse-down handler with the movement information as an upvalue
local function make_mousedown_handler (mwi)
return function (flags, hotspot_id)
local win = mwi.win
-- No resizing for locked windows
if (WINDATA[win]["LOCKED"] == true) then
return
end
-- find where mouse is so we can adjust window relative to mouse
mwi.startx = WindowInfo (win, 14)
mwi.starty = WindowInfo (win, 15)
-- find where window is in case we drag it offscreen
mwi.origx = WindowInfo (win, 10)
end
end -- make_mousedown_handler
-- make a mouse drag-move handler with the movement information as an upvalue
local function make_dragmove_handler (mwi)
return function (flags, hotspot_id)
local win = mwi.win
-- No resizing for locked windows, or for right-mouse
if (WINDATA[win]["LOCKED"] == true or bit.band(flags, miniwin.hotspot_got_rh_mouse) ~= 0) then
return
end
-- find where it is now
local posx, posy = WindowInfo(win, 17) - mwi.startx, WindowInfo(win, 18) - mwi.starty
-- change the mouse cursor shape appropriately
if posx < 0 or
posx > GetInfo (281) - mwi.margin or
posy < 0 or -- don't drag title out of view
posy > GetInfo (280) - mwi.margin then
SetCursor (miniwin.cursor_x)
else
SetCursor (miniwin.cursor_hand)
end -- if
if posx < 0 then
posx = 0
elseif posx > GetInfo (281) - mwi.margin then
posx = GetInfo(281) - mwi.margin
end
if posy < 0 then
posy = 0
elseif posy > GetInfo(280) - mwi.margin then
posy = GetInfo(280) - mwi.margin
end
-- move the window to the new location - offset by how far mouse was into window if different
if (posx ~= mwi.window_left or posy ~= mwi.window_top) then
WindowPosition(win, posx, posy, 0, miniwin.create_absolute_location);
mwi.window_left = posx
mwi.window_top = posy
mwi.window_mode = 0
mwi.window_flags = miniwin.create_absolute_location
iThemeLayoutLocked = 0
end
end -- dragmove
end -- make_dragmove_handler
-- make a mouse position-checking function with the movement information as an upvalue
local function make_check_map_position_handler (mwi)
return function ()
local win = mwi.win
if not WindowInfo (win, 1) then
ColourNote ("white", "red", "Error in make_check_map_position_handler: no window named: " .. win)
return
end -- no such window
-- check miniwindow visible
if mwi.window_left < 0 or
mwi.window_left > GetInfo (281) - mwi.margin or
mwi.window_top < 0 or -- don't drag title out of view
mwi.window_top > GetInfo (280) - mwi.margin then
mwi.window_left, mwi.window_top = 0, 0 -- reset to center right
mwi.window_mode = miniwin.pos_center_right
mwi.window_flags = 0
end -- if not visible
WindowPosition (win, mwi.window_left, mwi.window_top, mwi.window_mode, mwi.window_flags)
end -- check_map_position
end -- make_check_map_position_handler
function movewindow.install (win, default_position, default_flags, nocheck, start_position)
default_position = default_position or miniwin.pos_center_right -- on right, center top/bottom
default_flags = default_flags or 0
-- set up handlers and where window should be shown (from saved state, if any)
local movewindow_info = {
win = win, -- save window ID
-- save current position in table (obtained from state file)
window_left = tonumber (GetVariable ("mw_" .. win .. "_windowx")) or (start_position and start_position.x) or 0,
window_top = tonumber (GetVariable ("mw_" .. win .. "_windowy")) or (start_position and start_position.y) or 0,
window_mode = tonumber (GetVariable ("mw_" .. win .. "_windowmode")) or default_position,
window_flags = tonumber (GetVariable ("mw_" .. win .. "_windowflags")) or default_flags,
margin = 20, -- how close we can put to the edge of the window
}
-- handler to reposition window
movewindow_info.check_map_position = make_check_map_position_handler (movewindow_info) -- for startup
-- mouse handlers
movewindow_info.mousedown = make_mousedown_handler (movewindow_info)
movewindow_info.mouseup = ""
movewindow_info.mouseover = ""
movewindow_info.cancelmouseover = ""
movewindow_info.cancelmousedown = ""
movewindow_info.dragmove = make_dragmove_handler (movewindow_info)
movewindow_info.dragrelease = ""
-- save table in global namespace
_G ["mw_" .. win .. "_movewindow_info"] = movewindow_info
-- give main world window time to stabilize its size and position
-- eg. this might be: mw_23c3c91af0a26790c625f5d1_movewindow_info.check_map_position ()
if not nocheck then -- if wanted
DoAfterSpecial (5, "mw_" .. win .. "_movewindow_info.check_map_position ()" , sendto.script)
end -- if
return movewindow_info -- the caller might appreciate access to this table
end -- movewindow.install
-- call movewindow.add_drag_handler after creating the window, and after deleting hotspots where applicable
-- to add a drag hotspot
function movewindow.add_drag_handler (win, left, top, right, bottom, cursor)
win = win or GetPluginID () -- default to current plugin ID
-- the zz puts it under other hotspots on the drag area
local hotspot_id = "zz_mw_" .. win .. "_movewindow_hotspot"
if not WindowInfo (win, 1) then
ColourNote ("white", "red", "Error in movewindow.add_drag_handler: no window named: " .. win)
return
end -- no such window
-- make a hotspot
WindowAddHotspot(win, hotspot_id,
left or 0, top or 0, right or 0, bottom or 0, -- rectangle
"mw_" .. win .. "_movewindow_info.mouseover", -- MouseOver
"mw_" .. win .. "_movewindow_info.cancelmouseover", -- CancelMouseOver
"mw_" .. win .. "_movewindow_info.mousedown", -- MouseDown
"mw_" .. win .. "_movewindow_info.cancelmousedown", -- CancelMouseDown
"mw_" .. win .. "_movewindow_info.mouseup", -- MouseUp
"", -- tooltip text
cursor or miniwin.cursor_hand, -- cursor
0) -- flags
WindowDragHandler (win, hotspot_id,
"mw_" .. win .. "_movewindow_info.dragmove",
"mw_" .. win .. "_movewindow_info.dragrelease",
0) -- flags
end -- movewindow.add_drag_handler
-- call movewindow.save_state in OnPluginSaveState
function movewindow.save_state (win)
win = win or GetPluginID () -- default to current plugin ID
-- get movewindow variable from global namespace
local mwi = _G ["mw_" .. win .. "_movewindow_info"]
if not mwi then
ColourNote ("white", "red", "Error in movewindow.save_state: no window movement info for: " .. win)
return
end -- no such window
-- remember where the window was
SetVariable ("mw_" .. win .. "_windowx", mwi.window_left)
SetVariable ("mw_" .. win .. "_windowy", mwi.window_top)
SetVariable ("mw_" .. win .. "_windowmode", mwi.window_mode)
SetVariable ("mw_" .. win .. "_windowflags", mwi.window_flags)
-- use actual position, not where we happen to think it is, in case another plugin moves it
-- suggested by Fiendish, 27 August 2012.
if WindowInfo (win, 10) then
SetVariable ("mw_" .. win .. "_windowx", WindowInfo(win, 10))
end
if WindowInfo (win, 11) then
SetVariable ("mw_" .. win .. "_windowy", WindowInfo(win, 11))
end
end -- movewindow.save_state
winThemeData = {
WINDOW_BACKGROUND = ColourNameToRGB ("#000000"), -- for miniwindow body
WINDOW_BORDER = ColourNameToRGB("#E8E8E8"), -- for miniwindow body
HIGHLIGHT=ColourNameToRGB("#FFFFFF"), -- for 3D surfaces
FACE=ColourNameToRGB("#D4D0C8"), -- for 3D surfaces
INNERSHADOW=ColourNameToRGB("#808080"), -- for 3D surfaces
OUTERSHADOW = ColourNameToRGB("#404040"), -- for 3D surfaces
BACK_FACE = ColourNameToRGB ("#E8E8E8"), -- for contrasting details
DETAIL = ColourNameToRGB ("#000000"), -- for contrasting details
TITLE_HEIGHT = 17, -- for miniwindow title area
SUBTITLE_HEIGHT = 17, -- for miniwindow title area
TITLE_FONT_NAME = "Dina", -- for miniwindow title area
TITLE_FONT_SIZE = 8 -- for miniwindow title area
}
-- Replacement for WindowRectOp action 5, which allows for a 3D look while maintaining color winThemeData
-- Requires global winThemeData.HIGHLIGHT, winThemeData.FACE, winThemeData.INNERSHADOW, and winThemeData.OUTERSHADOW rgb colors to be set.
function DrawThemed3DRect(winThisWindow, left, top, right, bottom)
right = right + 1
WindowRectOp(winThisWindow, miniwin.rect_fill, left, top, right, bottom, winThemeData.FACE)
WindowLine(winThisWindow, left, top, right, top, winThemeData.HIGHLIGHT, miniwin.pen_solid + miniwin.pen_endcap_flat, 1)
WindowLine(winThisWindow, left, top, left, bottom, winThemeData.HIGHLIGHT, miniwin.pen_solid + miniwin.pen_endcap_flat, 1)
WindowLine(winThisWindow, left, bottom-2, right, bottom-2, winThemeData.INNERSHADOW, miniwin.pen_solid + miniwin.pen_endcap_flat, 1)
WindowLine(winThisWindow, right-2, top, right-2, bottom-2, winThemeData.INNERSHADOW, miniwin.pen_solid + miniwin.pen_endcap_flat, 1)
WindowLine(winThisWindow, left, bottom-1, right, bottom-1, winThemeData.OUTERSHADOW, miniwin.pen_solid + miniwin.pen_endcap_flat, 1)
WindowLine(winThisWindow, right-1, top, right-1, bottom-1, winThemeData.OUTERSHADOW, miniwin.pen_solid + miniwin.pen_endcap_flat, 1)
end
iGlobalFontHeight = 0
iGlobalLineHeight = 0
iGlobalFontWidth = 0
-- Intercept for the movewindow mouseup handle, replace with my own function
function MakeMouseupHandler(winAssignedWindow)
return function (flags, hotspot_id)
ReorderWindows(winAssignedWindow)
if (bit.band(flags, miniwin.hotspot_got_rh_mouse) ~= 0) then
-- Right click bring up menu - build the custom menu here
-- ! : return numeric result (only in first position of entire string)
-- - : separator line
-- ^ : grayed-out item
-- + : checked (ticked) item
-- > : start of nested menu (rest of line is nested menu title)
-- < : end of nested menu (rest of line is ignored)
local sMenuString = ""
-- XP window
if (winAssignedWindow == winXP) then
sMenuString = "^XP Window Controls:|-|"
elseif (winAssignedWindow == winMinimap) then
sMenuString = "^Minimap UI Controls:|-|"
elseif (winAssignedWindow == winBars) then
sMenuString = "^Character Vitals Controls:|-|"
elseif (winAssignedWindow == winStats) then
sMenuString = "^Combat Stats Controls:|-|"
elseif (winAssignedWindow == winMDT) then
sMenuString = "^Written-Map Controls:|-|"
elseif (winAssignedWindow == winShields) then
sMenuString = "^Shields Controls:|-|"
elseif (winAssignedWindow == winComms) then
sMenuString = "^Comms Controls:|-|"
elseif (winAssignedWindow == winAscii) then
sMenuString = "^Ascii-Map Controls:|-|"
end
-- XP window
if (winAssignedWindow == winXP) then
if (WINDATA[winXP]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock XP Window Position|"
sMenuString = sMenuString .. "Hide XP Window|-|"
elseif (winAssignedWindow == winMinimap) then
if (WINDATA[winMinimap]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Minimap Window Position|"
sMenuString = sMenuString .. "Hide Minimap Window|"
-- Character vitals bars window
elseif (winAssignedWindow == winBars) then
if (WINDATA[winBars]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Vitals Window Position|"
sMenuString = sMenuString .. "Hide Vitals Window|-|"
-- Combat stats window menu options
elseif (winAssignedWindow == winStats) then
if (WINDATA[winStats]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Combat Stats Window Position|"
sMenuString = sMenuString .. "Hide Combat Stats Window|-|"
-- MDT window menu options
elseif (winAssignedWindow == winMDT) then
if (WINDATA[winMDT]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Written Map Window Position|"
sMenuString = sMenuString .. "Hide Written Map Window|-|"
-- Shields window menu options
elseif (winAssignedWindow == winShields) then
if (WINDATA[winShields]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Shields Window Position|"
sMenuString = sMenuString .. "Hide Shields Window|-|"
-- Comms window menu options
elseif (winAssignedWindow == winComms) then
if (WINDATA[winComms]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Comms Window Position|"
sMenuString = sMenuString .. "Hide Comms Window|-|"
elseif (winAssignedWindow == winAscii) then
if (WINDATA[winAscii]["LOCKED"] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Ascii-Map Window Position|"
sMenuString = sMenuString .. "Hide Ascii-Map Window|-|"
end
sMenuString = sMenuString .. ">Screen Margins...|"
if (bLockMargins == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Lock Screen Margins|-|"
if (SCREENMARGINS["left"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Left Edge Margin|"
if (SCREENMARGINS["top"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Top Edge Margin|"
if (SCREENMARGINS["right"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Right Edge Margin|"
if (SCREENMARGINS["bottom"][1] == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Bottom Edge Margin|"
sMenuString = sMenuString .. "<|"
-- Instant layouts
sMenuString = sMenuString .. ">Instant Layouts...|"
sMenuString = sMenuString .. "^Auto-Configure Full Layout:|-|"
if (iThemeLayoutLocked == 11) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Simple Cow|-|"
if (iThemeLayoutLocked == 2) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Left|"
if (iThemeLayoutLocked == 3) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Right|"
if (iThemeLayoutLocked == 1) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Top|"
if (iThemeLayoutLocked == 4) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Cow-Bar Classic Bottom|"
sMenuString = sMenuString .. "-|"
if (iThemeLayoutLocked == 8) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Semi-Skimmed Top|"
if (iThemeLayoutLocked == 9) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Semi-Skimmed Bottom|"
sMenuString = sMenuString .. "-|"
if (iThemeLayoutLocked == 5) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Micro-Cow Miniatures|"
if (iThemeLayoutLocked == 7) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Marginalised Cows|"
if (iThemeLayoutLocked == 6) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Big-Cows Big-Windows|"
sMenuString = sMenuString .. "-|"
if (iThemeLayoutLocked == 10) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Load Custom Cows Layout|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Save Custom Cows Layout|"
sMenuString = sMenuString .. "<|"
-- XP window
if (winAssignedWindow == winXP) then
sMenuString = sMenuString .. "-|^XP Window:|-|"
if (bShowXPNotifications == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show XP Gain Notification Texts|"
sMenuString = sMenuString .. "Reset XP Rate|-|"
if (iTotalGroupMembers == 0) then sMenuString = sMenuString .. "^" end
sMenuString = sMenuString .. "Group Say XP Rate|"
sMenuString = sMenuString .. "Show XP Report|"
elseif (winAssignedWindow == winMinimap) then
sMenuString = sMenuString .. "-|^Right click the main minimap area for full options|"
-- Character vitals bars window
elseif (winAssignedWindow == winBars) then
sMenuString = sMenuString .. "-|^Vitals Window:|-|"
sMenuString = sMenuString .. ">Colour Vitals Bars...|"
sMenuString = sMenuString .. "Colour: HP Full Colour|"
sMenuString = sMenuString .. "Colour: HP Half Colour|"
sMenuString = sMenuString .. "Colour: HP Low Colour|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Colour: GP Full Colour|"
sMenuString = sMenuString .. "Colour: GP Half Colour|"
sMenuString = sMenuString .. "Colour: GP Low Colour|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Colour: Burden Empty Colour|"
sMenuString = sMenuString .. "Colour: Burden Half Colour|"
sMenuString = sMenuString .. "Colour: Burden Heavy Colour|"
sMenuString = sMenuString .. "<|-|"
sMenuString = sMenuString .. ">Change Set To...|"
for iN = 1, #iQuowCombatStats do
if (iN == iCurrentCombatStatSet) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "[Set " .. iN .. "] " .. iQuowCombatStats[iN]["set_name"] .. "|"
end
sMenuString = sMenuString .. "<|-|>GP Regeneration For This Set...|"
for iN = 0, 4 do
if (iQuowCombatStats[iCurrentCombatStatSet]["gp_regen"] == iN) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "GP Regen " .. iN .. "|"
end
sMenuString = sMenuString .. "<|-|>GP Full Notification...|"
sMenuString = sMenuString .. "Choose GP Full Wav File Sound|-|"
if (bPlayGPNotification == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Play Sound On Full GP|"
sMenuString = sMenuString .. "<|-|"
if (bShowHPNotifications == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show HP Loss Notification Texts|"
if (bVitalStacking == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Stack Bars Vertically|"
-- Ascii-Map window
elseif (winAssignedWindow == winAscii) then
sMenuString = sMenuString .. "-|^ASCII Map Window:|-|"
if (bAutoShowHideAscii == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Auto-Hide-Show ASCII map with terrains|"
if (bAsciiMapOmitted == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Omit ASCII map from MUD output|"
-- Comms window
elseif (winAssignedWindow == winComms) then
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. ">Font Options...|"
if (sUserFont == "FixedSys") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font: FixedSys|"
if (sUserFont == "Courier") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font: Courier|"
if (sUserFont == "Courier New") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font: Courier New|"
if (sUserFont == "Consolas") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font: Consolas|"
if (sUserFont == "Lucida Console") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font: Lucida Console|-|"
if (iFontSize == 8) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font-Size: 8|"
if (iFontSize == 10) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font-Size: 10|"
if (iFontSize == 12) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Font-Size: 12|"
sMenuString = sMenuString .. "<|"
if (bShowCommsTabs == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show Chat Tabs|"
sMenuString = sMenuString .. "Add New Custom Chat Tab|"
sMenuString = sMenuString .. ">Modify Chat Tab...|"
for iN = 1, #objChatTabs do
sMenuString = sMenuString .. "Modify Chat Tab " .. iN .. ": " .. objChatTabs[iN][1] .. "|"
end
sMenuString = sMenuString .. "<|>Delete Chat Tab...|"
if (#objChatTabs > 1) then
for iN = 1, #objChatTabs do
sMenuString = sMenuString .. "Delete Chat Tab " .. iN .. ": " .. objChatTabs[iN][1] .. "|"
end
else
sMenuString = sMenuString .. "^Cannot delete final chat tab|^Create a new tab first|"
end
sMenuString = sMenuString .. "<|-|"
sMenuString = sMenuString .. "Record New Talker/Club Channel|"
sMenuString = sMenuString .. ">Stop Recording Talker/Club Channel...|"
local bAnyToStop = false
for sKey, sData in pairs(objChatFilters) do
if (sKey ~= "Tells_In" and sKey ~= "Tells_Out" and sKey ~= "Group_Say") then
bAnyToStop = true
sMenuString = sMenuString .. "Stop Recording: " .. sKey .. "|"
end
end
if (bAnyToStop == false) then
sMenuString = sMenuString .. "^Not recording any channels|"
end
sMenuString = sMenuString .. "<|-|>Echo Channels to Main Output...|"
sMenuString = sMenuString .. "^Ticked options are ECHOED/SHOWN in MUD output|-|"
if (objChatFilters["Group_Say"][3] == false) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Echo Main Output: Group Say|"
for sKey, sData in pairs(objChatFilters) do
if (sKey ~= "Tells_In" and sKey ~= "Tells_Out" and sKey ~= "Group_Say") then
if (sData[3] == false) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Echo Main Output: " .. sKey .. "|"
end
end
sMenuString = sMenuString .. "<|-|Copy All Messages To Clipboard|"
sMenuString = sMenuString .. "Copy Selected Line To Clipboard|"
-- Shields window
elseif (winAssignedWindow == winShields) then
sMenuString = sMenuString .. "-|^Group And Shields Window:|-|"
if (iTotalGroupMembers == 0) then sMenuString = sMenuString .. "^" end
sMenuString = sMenuString .. "Group Say Group Kills Report|"
if (iTotalGroupMembers == 0) then sMenuString = sMenuString .. "^" end
sMenuString = sMenuString .. "Show Private Group Kills Report|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Refresh Solo Character Shields|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Refresh Group Status and Shields|"
-- Combat stats window menu options
elseif (winAssignedWindow == winStats) then
sMenuString = sMenuString .. "-|^Combat Stats Window:|-|"
sMenuString = sMenuString .. ">Re-Colour MUD Combat Texts...|"
sMenuString = sMenuString .. "^TICKED Messages Are Re-Coloured By Plugin:|-|"
if (sUSER_OPTIONS["nocol_special_prep"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: You prepare a special|"
if (sUSER_OPTIONS["nocol_special_fail"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: You fail to prepare a special|"
sMenuString = sMenuString .. "-|"
if (sUSER_OPTIONS["nocol_special_out_fail"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: You special enemy but they defend|"
if (sUSER_OPTIONS["nocol_special_out_success"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: You special and hurt enemy|"
if (sUSER_OPTIONS["nocol_melee_out_fail"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: You hit enemy but they defend|"
if (sUSER_OPTIONS["nocol_melee_out_success"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: You hit and hurt enemy|"
if (sUSER_OPTIONS["nocol_melee_out_kill"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: You kill enemy|"
sMenuString = sMenuString .. "-|"
if (sUSER_OPTIONS["nocol_special_inc_fail"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Enemy specials you but you defend|"
if (sUSER_OPTIONS["nocol_special_inc_success"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Enemy specials and hurts you|"
if (sUSER_OPTIONS["nocol_melee_inc_fail"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Enemy hits you but you defend|"
if (sUSER_OPTIONS["nocol_melee_inc_success"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Enemy hits and hurts you|"
if (sUSER_OPTIONS["nocol_melee_inc_kill"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Enemy kills you|"
sMenuString = sMenuString .. "-|"
if (sUSER_OPTIONS["nocol_special_third_fail"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Others special others who defend|"
if (sUSER_OPTIONS["nocol_special_third_success"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Others special and hurt others|"
if (sUSER_OPTIONS["nocol_melee_third_fail"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Others hit others who defend|"
if (sUSER_OPTIONS["nocol_melee_third_success"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Others hit and hurt others|"
if (sUSER_OPTIONS["nocol_melee_third_kill"] == "17") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Re-Colour: Others kill others|"
sMenuString = sMenuString .. "<|"
sMenuString = sMenuString .. ">Change MUD Combat Text Colours...|"
sMenuString = sMenuString .. "Show message samples in output|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Pick Colour: You prepare a special|"
sMenuString = sMenuString .. "Pick Colour: You fail to prepare a special|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Pick Colour: You special enemy but they defend|"
sMenuString = sMenuString .. "Pick Colour: You special and hurt enemy|"
sMenuString = sMenuString .. "Pick Colour: You hit enemy but they defend|"
sMenuString = sMenuString .. "Pick Colour: You hit and hurt enemy|"
sMenuString = sMenuString .. "Pick Colour: You kill enemy|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Pick Colour: Enemy specials you but you defend|"
sMenuString = sMenuString .. "Pick Colour: Enemy specials and hurts you|"
sMenuString = sMenuString .. "Pick Colour: Enemy hits you but you defend|"
sMenuString = sMenuString .. "Pick Colour: Enemy hits and hurts you|"
sMenuString = sMenuString .. "Pick Colour: Enemy kills you|"
sMenuString = sMenuString .. "-|"
sMenuString = sMenuString .. "Pick Colour: Others special others who defend|"
sMenuString = sMenuString .. "Pick Colour: Others special and hurt others|"
sMenuString = sMenuString .. "Pick Colour: Others hit others who defend|"
sMenuString = sMenuString .. "Pick Colour: Others hit and hurt others|"
sMenuString = sMenuString .. "Pick Colour: Others kill others|"
sMenuString = sMenuString .. "<|"
sMenuString = sMenuString .. ">Hide MUD Combat Texts...|"
sMenuString = sMenuString .. "^UNTICK to HIDE message type|"
sMenuString = sMenuString .. "-|"
if (sUSER_OPTIONS["omit_special_prep"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: You prepare a special|"
if (sUSER_OPTIONS["omit_special_fail"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: You fail to prepare a special|"
sMenuString = sMenuString .. "-|"
if (sUSER_OPTIONS["omit_special_out_fail"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: You special enemy but they defend|"
if (sUSER_OPTIONS["omit_special_out_success"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: You special and hurt enemy|"
if (sUSER_OPTIONS["omit_melee_out_fail"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: You hit enemy but they defend|"
if (sUSER_OPTIONS["omit_melee_out_success"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: You hit and hurt enemy|"
if (sUSER_OPTIONS["omit_melee_out_kill"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: You kill enemy|"
sMenuString = sMenuString .. "-|"
if (sUSER_OPTIONS["omit_special_inc_fail"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Enemy specials you but you defend|"
if (sUSER_OPTIONS["omit_special_inc_success"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Enemy specials and hurts you|"
if (sUSER_OPTIONS["omit_melee_inc_fail"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Enemy hits you but you defend|"
if (sUSER_OPTIONS["omit_melee_inc_success"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Enemy hits and hurts you|"
if (sUSER_OPTIONS["omit_melee_inc_kill"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Enemy kills you|"
sMenuString = sMenuString .. "-|"
if (sUSER_OPTIONS["omit_special_third_fail"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Others special others who defend|"
if (sUSER_OPTIONS["omit_special_third_success"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Others special and hurt others|"
if (sUSER_OPTIONS["omit_melee_third_fail"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Others hit others who defend|"
if (sUSER_OPTIONS["omit_melee_third_success"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Others hit and hurt others|"
if (sUSER_OPTIONS["omit_melee_third_kill"] == "n") then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Show: Others kill others|"
sMenuString = sMenuString .. "<|-|"
if (bOptimisedCombatTriggers == true) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "Optimize Plugin Combat Triggers|-|"
sMenuString = sMenuString .. ">Change Set To...|"
for iN = 1, #iQuowCombatStats do
if (iN == iCurrentCombatStatSet) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "[Set " .. iN .. "] " .. iQuowCombatStats[iN]["set_name"] .. "|"
end
sMenuString = sMenuString .. "<|>GP Regeneration For This Set...|"
for iN = 0, 4 do
if (iQuowCombatStats[iCurrentCombatStatSet]["gp_regen"] == iN) then
sMenuString = sMenuString .. "+"
end
sMenuString = sMenuString .. "GP Regen " .. iN .. "|"
end
sMenuString = sMenuString .. "<|"
sMenuString = sMenuString .. "Rename Current Set|"
sMenuString = sMenuString .. "Reset Current Set Stats|-|"
sMenuString = sMenuString .. "Generate Full Stat Report|"
end
iCommLineClicked = WindowInfo(winAssignedWindow, 15)
sRMBResult = WindowMenu (winAssignedWindow, WindowInfo(winAssignedWindow, 14), iCommLineClicked, sMenuString)
if (sRMBResult ~= "") then
local iNewColour
local sColourOption
if (sRMBResult == "Add New Custom Chat Tab") then
local sNewChatTabName = utils.inputbox("Enter a name for your new chat tab.\n\nKeep it simple, and short, eg 'All', 'Tells', 'Priests', 'Clubs'.", "New Chat Tab Name", "", "", 12)
if (sNewChatTabName ~= nil and sNewChatTabName ~= "") then
local bUniqueChannel = true
for iN = 1, #objChatTabs do
if (objChatTabs[iN][1] == sNewChatTabName) then
bUniqueChannel = false
break
end
end
if (bUniqueChannel == true) then
local sTabChoices = {"*All*", "*All Talkers/Clubs*", "*Tells*", "*Group*"}
for sKey, sData in pairs(objChatFilters) do
if (sKey ~= "Tells_In" and sKey ~= "Tells_Out" and sKey ~= "Group_Say") then
table.insert(sTabChoices, sKey)
end
end
local sTabSelected = utils.multilistbox ("Select comms channels to display for a new '" .. sNewChatTabName .. "' tab.\nCtrl-click and shift-click for multiple selections.\n\nMissing a talker/club channel?\n'Record New Talker/Club Channel' in the menu.\n", "Comms Channels:", sTabChoices, nil)
if (sTabSelected ~= nil) then
local sMyChatChoices = {}
local bAllTalkers = false
for sKey, sData in pairs(sTabSelected) do
if (sTabChoices[sKey] == "*All*") then
sMyChatChoices = {"*All*"}
break
elseif (sTabChoices[sKey] == "*All Talkers/Clubs*") then
table.insert(sMyChatChoices, "*Talkers*")
bAllTalkers = true
elseif (sTabChoices[sKey] == "*Tells*") then
table.insert(sMyChatChoices, "Tells_In")
table.insert(sMyChatChoices, "Tells_Out")
elseif (sTabChoices[sKey] == "*Group*") then
table.insert(sMyChatChoices, "Group_Say")
elseif (bAllTalkers == false) then
table.insert(sMyChatChoices, sTabChoices[sKey])
end
end
table.insert(objChatTabs, {sNewChatTabName, sMyChatChoices})
RedrawCommsWindow()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Added new custom comms window chat-tab named '" .. sNewChatTabName .. "'")
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You did not select any comms channels to display, cancelling creation of new chat-tab.")
end
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "A chat-tab already exists with the name '" .. sNewChatTabName .. "', you must delete the old one first before re-creating it.")
end
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You did not enter a chat-tab name, cancelling creation of new chat-tab.")
end
elseif (string.sub(sRMBResult, 1, 16) == "Modify Chat Tab ") then
sRMBResult = string.sub(sRMBResult, 17)
local iWhere = string.find(sRMBResult, ":")
local iThisTab = tonumber(string.sub(sRMBResult, 1, iWhere - 1))
sRMBResult = string.sub(sRMBResult, iWhere + 2)
local sNewChatTabName = utils.inputbox("Enter a new name for the chat tab '" .. sRMBResult .. "'.\n\nKeep it simple, and short, eg 'All', 'Tells', 'Priests', 'Clubs'.", "Rename Chat Tab", sRMBResult, "", 12)
if (sNewChatTabName ~= nil and sNewChatTabName ~= "") then
local sTabChoices = {"*All*", "*All Talkers/Clubs*", "*Tells*", "*Group*"}
local iMyChoices = {}
for sKey, sData in pairs(objChatFilters) do
if (sKey ~= "Tells_In" and sKey ~= "Tells_Out" and sKey ~= "Group_Say") then
table.insert(sTabChoices, sKey)
end
end
for sKey, sData in pairs(objChatTabs[iThisTab][2]) do
if (sData == "*All*") then
iMyChoices[1] = true
elseif (sData == "*Talkers*") then
iMyChoices[2] = true
elseif (sData == "Tells_In" or sData == "Tells_Out") then
iMyChoices[3] = true
elseif (sData == "Group_Say") then
iMyChoices[4] = true
else
for iTabKey, sTabData in ipairs(sTabChoices) do
if (sTabData == sData) then
iMyChoices[iTabKey] = true
end
end
end
end
local sTabSelected = utils.multilistbox ("Select comms channels to display for '" .. sRMBResult .. "' tab.\nCtrl-click and shift-click for multiple selections.\n\nMissing a talker/club channel?\n'Record New Talker/Club Channel' in the menu.\n", "Comms Channels:", sTabChoices, iMyChoices)
if (sTabSelected ~= nil) then
local sMyChatChoices = {}
objChatTabs[iThisTab][2] = nil
local bAllTalkers = false
for sKey, sData in pairs(sTabSelected) do
if (sTabChoices[sKey] == "*All*") then
sMyChatChoices = {"*All*"}
break
elseif (sTabChoices[sKey] == "*All Talkers/Clubs*") then
table.insert(sMyChatChoices, "*Talkers*")
bAllTalkers = true
elseif (sTabChoices[sKey] == "*Tells*") then
table.insert(sMyChatChoices, "Tells_In")
table.insert(sMyChatChoices, "Tells_Out")
elseif (sTabChoices[sKey] == "*Group*") then
table.insert(sMyChatChoices, "Group_Say")
elseif (bAllTalkers == false) then
table.insert(sMyChatChoices, sTabChoices[sKey])
end
end
objChatTabs[iThisTab][1] = sNewChatTabName
objChatTabs[iThisTab][2] = sMyChatChoices
if (iThisTab == iCurrentChannelChoice) then
ChangeChatChannel(iCurrentChannelChoice)
end
RedrawCommsWindow()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Chat-tab '" .. sRMBResult .. "' has been updated and renamed to '" .. sNewChatTabName .. "'")
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Cancelling modification of chat-tab '" .. sRMBResult .. "'")
end
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Cancelling modification of chat-tab '" .. sRMBResult .. "'")
end
elseif (string.sub(sRMBResult, 1, 16) == "Delete Chat Tab ") then
sRMBResult = string.sub(sRMBResult, 17)
local iWhere = string.find(sRMBResult, ":")
local iDeleteTab = tonumber(string.sub(sRMBResult, 1, iWhere - 1))
sRMBResult = string.sub(sRMBResult, iWhere + 2)
if (iDeleteTab ~= 0) then
table.remove(objChatTabs, iDeleteTab)
iCurrentChannelChoice = 1
iCommsMessagesCurrentlyShown = 0
for sKey, sData in pairs(objChatFilters) do
objChatFilters[sKey][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sKey]
end
iCommLineBottomRender = iCommsMessagesCurrentlyShown
RedrawCommsWindow()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have deleted the chat-tab named '" .. sRMBResult .. "'")
end
-- Pre-configured layout themes
elseif (sRMBResult == "Simple Cow") then
QuowLayoutTheme(11)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Top") then
QuowLayoutTheme(1)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Left") then
QuowLayoutTheme(2)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Right") then
QuowLayoutTheme(3)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Cow-Bar Classic Bottom") then
QuowLayoutTheme(4)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Micro-Cow Miniatures") then
QuowLayoutTheme(5)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Big-Cows Big-Windows") then
QuowLayoutTheme(6)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Marginalised Cows") then
QuowLayoutTheme(7)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Semi-Skimmed Top") then
QuowLayoutTheme(8)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Semi-Skimmed Bottom") then
QuowLayoutTheme(9)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: " .. sRMBResult)
elseif (sRMBResult == "Load Custom Cows Layout") then
QuowLayoutTheme(10)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset and repositioned all of your windows to the layout: Custom Cows")
elseif (sRMBResult == "Save Custom Cows Layout") then
CallPlugin ("bfe35205f026786ea1d56e3b", "QuowSaveCustomCows", "", "")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your current exact window positions and sizes have been saved to the Custom Cows layout.")
-- Lock XP Window Position
elseif (sRMBResult == "Lock XP Window Position") then
if (WINDATA[winXP]["LOCKED"] == true) then
WINDATA[winXP]["LOCKED"] = false
else
WINDATA[winXP]["LOCKED"] = true
end
-- Lock Vitals Window Position
elseif (sRMBResult == "Lock Vitals Window Position") then
if (WINDATA[winBars]["LOCKED"] == true) then
WINDATA[winBars]["LOCKED"] = false
else
WINDATA[winBars]["LOCKED"] = true
end
-- Lock Stats Window Position
elseif (sRMBResult == "Lock Combat Stats Window Position") then
if (WINDATA[winStats]["LOCKED"] == true) then
WINDATA[winStats]["LOCKED"] = false
else
WINDATA[winStats]["LOCKED"] = true
end
-- Lock MDT Window Position
elseif (sRMBResult == "Lock Written Map Window Position") then
if (WINDATA[winMDT]["LOCKED"] == true) then
WINDATA[winMDT]["LOCKED"] = false
else
WINDATA[winMDT]["LOCKED"] = true
end
-- Lock Minimap Window Position
elseif (sRMBResult == "Lock Minimap Window Position") then
if (WINDATA[winMinimap]["LOCKED"] == true) then
WINDATA[winMinimap]["LOCKED"] = false
else
WINDATA[winMinimap]["LOCKED"] = true
end
elseif (sRMBResult == "Hide Minimap Window") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Hiding the minimap window. Use '", sGlobalColourCyan, sGlobalColourBlack, "minimap show", sGlobalColourOrange, sGlobalColourBlack, "' to display again.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Note: MANY options and features of Cow Bar are controlled through the minimap window menu!")
WindowShow(winMinimap, false)
WINDATA[winMinimap]["SHOW"] = false
iThemeLayoutLocked = 0
bMinimapHidden = true
bMinimapTempHidden = false
-- Lock Shields Window Position
elseif (sRMBResult == "Lock Shields Window Position") then
if (WINDATA[winShields]["LOCKED"] == true) then
WINDATA[winShields]["LOCKED"] = false
else
WINDATA[winShields]["LOCKED"] = true
end
-- Lock Comms Window Position
elseif (sRMBResult == "Lock Comms Window Position") then
if (WINDATA[winComms]["LOCKED"] == true) then
WINDATA[winComms]["LOCKED"] = false
else
WINDATA[winComms]["LOCKED"] = true
end
-- Lock Ascii-Map Window Position
elseif (sRMBResult == "Lock Ascii-Map Window Position") then
if (WINDATA[winAscii]["LOCKED"] == true) then
WINDATA[winAscii]["LOCKED"] = false
else
WINDATA[winAscii]["LOCKED"] = true
end
-- HIDE XP Window
elseif (sRMBResult == "Hide XP Window") then
WINDATA[winXP]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winXP, false)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have hidden the XP window.")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winXP .. ")", "Click here to show it again", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, " (or from the minimap right-click, extra windows sub-menu)")
-- HIDE Vitals Window
elseif (sRMBResult == "Hide Vitals Window") then
WINDATA[winBars]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winBars, false)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have hidden the Vitals window.")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winBars .. ")", "Click here to show it again", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, " (or from the minimap right-click, extra windows sub-menu)")
-- HIDE Stats Window
elseif (sRMBResult == "Hide Combat Stats Window") then
WINDATA[winStats]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winStats, false)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have hidden the Combat Stats window.")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winStats .. ")", "Click here to show it again", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, " (or from the minimap right-click, extra windows sub-menu)")
-- HIDE MDT Window
elseif (sRMBResult == "Hide Written Map Window") then
WINDATA[winMDT]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winMDT, false)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have hidden the Written Map window.")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winMDT .. ")", "Click here to show it again", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, " (or from the minimap right-click, extra windows sub-menu)")
-- HIDE Shields Window
elseif (sRMBResult == "Hide Shields Window") then
WINDATA[winShields]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winShields, false)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have hidden the Shields window.")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winShields .. ")", "Click here to show it again", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, " (or from the minimap right-click, extra windows sub-menu)")
-- HIDE Comms Window
elseif (sRMBResult == "Hide Comms Window") then
WINDATA[winComms]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winComms, false)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have hidden the Comms window.")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winComms .. ")", "Click here to show it again", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, " (or from the minimap right-click, extra windows sub-menu)")
-- HIDE Comms Window
elseif (sRMBResult == "Hide Ascii-Map Window") then
WINDATA[winAscii]["SHOW"] = false
iThemeLayoutLocked = 0
WindowShow(winAscii, false)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have hidden the Ascii-Map window.")
Hyperlink ("!!bfe35205f026786ea1d56e3b:QuowShowWindow(" .. winAscii .. ")", "Click here to show it again", "", sGlobalColourCyan, "", 0)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, " (or from the minimap right-click, extra windows sub-menu)")
-- **************************
-- * Ascii Map menu options *
-- **************************
elseif (sRMBResult == "Auto-Hide-Show ASCII map with terrains") then
if (bAutoShowHideAscii == true) then
bAutoShowHideAscii = false
else
bAutoShowHideAscii = true
end
elseif (sRMBResult == "Omit ASCII map from MUD output") then
if (bAsciiMapOmitted == true) then
bAsciiMapOmitted = false
else
bAsciiMapOmitted = true
end
-- *********************************
-- * Communications Window options *
-- *********************************
elseif (sRMBResult == "Record New Talker/Club Channel") then
local sPopupResult = utils.inputbox("Enter the EXACT talker/club name to record.\n\nThis must be capitalised correctly.\n\nFor example 'Wizards' (without quotes).\n", "Comms Channel Record", "", "", 12)
if (sPopupResult ~= nil and objChatFilters[sPopupResult] == nil) then
sPopupResult = string.gsub(sPopupResult, " ", "_")
objChatFilters[sPopupResult] = {true, true, false}
table.insert(objChatTabs, {string.gsub(sPopupResult, "_", " "), {sPopupResult}})
iCommsCountByType[sPopupResult] = 0
CallPlugin ("bfe35205f026786ea1d56e3b", "QuowAddTalkerTrigger", sPopupResult)
iChatExtraChannels = iChatExtraChannels + 1
iCurrentChannelChoice = 1
iCommsMessagesCurrentlyShown = 0
for sKey, sData in pairs(objChatFilters) do
objChatFilters[sKey][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sKey]
end
iCommLineBottomRender = iCommsMessagesCurrentlyShown
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Now recording any talker messages from channel (" .. sPopupResult .. ")")
RedrawCommsWindow()
end
elseif (string.sub(sRMBResult, 1, 16) == "Stop Recording: ") then
sRMBResult = string.sub(sRMBResult, 17)
CallPlugin ("bfe35205f026786ea1d56e3b", "QuowDeleteTalkerTrigger", sRMBResult)
objChatFilters[sRMBResult] = nil
for iN = 1, #objChatTabs do
for sKey, sData in pairs(objChatTabs[iN][2]) do
if (sData == sRMBResult) then
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Custom chat-tab '" .. objChatTabs[iN][1] .. "' has been updated to remove '" .. sRMBResult .. "' from it.")
table.remove(objChatTabs[iN][2], sKey)
end
end
end
local iAnyToRemove = 1
local iChannelCount = 0
while (iAnyToRemove ~= 0) do
iAnyToRemove = 0
for iN = 1, #objChatTabs do
iChannelCount = 0
for sKey, sData in pairs(objChatTabs[iN][2]) do
iChannelCount = iChannelCount + 1
end
if (objChatTabs[iN][2] == nil or iChannelCount == 0) then
iAnyToRemove = iN
break
end
end
if (iAnyToRemove ~= 0) then
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Custom chat-tab '" .. objChatTabs[iAnyToRemove][1] .. "' has no associated recorded channels, deleting it.")
table.remove(objChatTabs, iAnyToRemove)
end
end
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown - iCommsCountByType[sRMBResult]
iCommsCountByType[sRMBResult] = nil
iChatExtraChannels = iChatExtraChannels - 1
iCurrentChannelChoice = 1
iCommsMessagesCurrentlyShown = 0
for sKey, sData in pairs(objChatFilters) do
objChatFilters[sKey][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sKey]
end
iCommLineBottomRender = iCommsMessagesCurrentlyShown
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "No longer recording or controlling talker channel (" .. sRMBResult .. ")")
RedrawCommsWindow()
elseif (string.sub(sRMBResult, 1, 15) == "Show Messages: ") then
sRMBResult = string.sub(sRMBResult, 16)
if (objChatFilters[sRMBResult][2] == true) then
objChatFilters[sRMBResult][2] = false
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown - iCommsCountByType[sRMBResult]
else
objChatFilters[sRMBResult][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sRMBResult]
end
iCommLineBottomRender = iCommsMessagesCurrentlyShown
RedrawCommsWindow()
elseif (string.sub(sRMBResult, 1, 6) == "Font: ") then
sRMBResult = string.sub(sRMBResult, 7)
sUserFont = sRMBResult
WindowFont(winMinimap, "bodyfont"..winMinimap, sUserFont, iFontSize)
WindowFont(winMDT, "bodyfont"..winMDT, sUserFont, iFontSize)
WindowFont(winComms, "bodyfont"..winComms, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii.."m", sUserFont, iFontSize + 2)
WindowFont(winAscii, "bodyfont"..winAscii.."l", sUserFont, iFontSize + 4)
iGlobalFontHeight = WindowFontInfo(winMinimap, "bodyfont"..winMinimap, 1) - WindowFontInfo(winMinimap, "bodyfont"..winMinimap, 4) + 1
iGlobalLineHeight = iGlobalFontHeight + 1
iGlobalFontWidth = WindowTextWidth(winMinimap, "bodyfont"..winMinimap, "W")
RedrawCommsWindow()
RedrawAsciiWindow()
RedrawMDTWindow()
RedrawMap()
Repaint()
elseif (string.sub(sRMBResult, 1, 11) == "Font-Size: ") then
sRMBResult = string.sub(sRMBResult, 12)
iFontSize = tonumber(sRMBResult)
WindowFont(winMinimap, "bodyfont"..winMinimap, sUserFont, iFontSize)
WindowFont(winMDT, "bodyfont"..winMDT, sUserFont, iFontSize)
WindowFont(winComms, "bodyfont"..winComms, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii.."m", sUserFont, iFontSize + 2)
WindowFont(winAscii, "bodyfont"..winAscii.."l", sUserFont, iFontSize + 4)
iGlobalFontHeight = WindowFontInfo(winMinimap, "bodyfont"..winMinimap, 1) - WindowFontInfo(winMinimap, "bodyfont"..winMinimap, 4) + 1
iGlobalLineHeight = iGlobalFontHeight + 1
iGlobalFontWidth = WindowTextWidth(winMinimap, "bodyfont"..winMinimap, "W")
RedrawCommsWindow()
RedrawAsciiWindow()
RedrawMDTWindow()
RedrawMap()
Repaint()
elseif (sRMBResult == "Show Chat Tabs") then
if (bShowCommsTabs == true) then
bShowCommsTabs = false
iTopCommsWindow = 0
WindowMoveHotspot(winComms, "hsCommsUp", WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH + 1), iTopCommsWindow, WINDATA[winComms]["WIDTH"]-1, SCROLL_BAR_WIDTH + iTopCommsWindow)
WindowMoveHotspot(winComms, "zz_mw_" .. winComms .. "_movewindow_hotspot", 0, iTopCommsWindow, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"])
WindowDeleteHotspot (winComms, "hsChatTabs")
bCommsNeedsButtons = true
RedrawCommsWindow()
else
bShowCommsTabs = true
iTopCommsWindow = winThemeData.TITLE_HEIGHT
WindowMoveHotspot(winComms, "hsCommsUp", WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH + 1), iTopCommsWindow, WINDATA[winComms]["WIDTH"]-1, SCROLL_BAR_WIDTH + iTopCommsWindow)
WindowMoveHotspot(winComms, "zz_mw_" .. winComms .. "_movewindow_hotspot", 0, iTopCommsWindow, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"])
WindowAddHotspot(winComms, "hsChatTabs", 0, 0, WINDATA[winComms]["WIDTH"], iTopCommsWindow, "", "", "", "", "ChatTabMouseUp", "", miniwin.cursor_hand, 0)
bCommsNeedsButtons = true
RedrawCommsWindow()
end
elseif (string.sub(sRMBResult, 1, 11) == "Show Only: ") then
sRMBResult = string.sub(sRMBResult, 12)
if (sRMBResult == "Tells") then
iCommsMessagesCurrentlyShown = iCommsCountByType["Tells_In"] + iCommsCountByType["Tells_Out"]
for sKey, sData in pairs(objChatFilters) do
objChatFilters[sKey][2] = false
end
objChatFilters["Tells_In"][2] = true
objChatFilters["Tells_Out"][2] = true
else
if (sRMBResult == "Tells In") then
sRMBResult = "Tells_In"
elseif (sRMBResult == "Tells Out") then
sRMBResult = "Tells_Out"
elseif (sRMBResult == "Group Say") then
sRMBResult = "Group_Say"
end
objChatFilters[sRMBResult][2] = true
for sKey, sData in pairs(objChatFilters) do
if (sKey ~= sRMBResult) then
objChatFilters[sKey][2] = false
end
end
iCommsMessagesCurrentlyShown = iCommsCountByType[sRMBResult]
end
iCommLineBottomRender = iCommsMessagesCurrentlyShown
RedrawCommsWindow()
elseif (sRMBResult == "Show All Messages") then
iCommsMessagesCurrentlyShown = 0
for sKey, sData in pairs(objChatFilters) do
objChatFilters[sKey][2] = true
iCommsMessagesCurrentlyShown = iCommsMessagesCurrentlyShown + iCommsCountByType[sKey]
end
iCommLineBottomRender = iCommsMessagesCurrentlyShown
RedrawCommsWindow()
elseif (sRMBResult == "Copy All Messages To Clipboard") then
local sMessageBuffer = ""
local iShownMessages = 0
for iC = 1, #sCommsBuffer do
-- Is this a type of message we CURRENTLY want to display?
if (objChatFilters[sCommsBuffer[iC][1]][2] == true) then
-- Loop through the styles
for iStyleKey, sThisStyle in ipairs (sCommsBuffer[iC][3]) do
sMessageBuffer = sMessageBuffer .. sThisStyle.text
end
iShownMessages = iShownMessages + 1
sMessageBuffer = sMessageBuffer .. "\n"
end
end
SetClipboard(sMessageBuffer)
sMessageBuffer = nil
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "All filtered messages copied to clipboard [" .. iShownMessages .. " messages]")
iShownMessages = nil
elseif (sRMBResult == "Copy Selected Line To Clipboard") then
RedrawCommsWindow(iCommLineClicked)
elseif (string.sub(sRMBResult, 1, 18) == "Echo Main Output: ") then
sRMBResult = string.sub(sRMBResult, 19)
if (sRMBResult == "Group Say") then
sRMBResult = "Group_Say"
end
if (objChatFilters[sRMBResult][3] == true) then
objChatFilters[sRMBResult][3] = false
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Now showing/echoing '" .. sRMBResult .. "' in main MUD output.")
if (sRMBResult ~= "Group_Say") then
sRMBResult = "CommLog_" .. string.gsub(sRMBResult, "-", "_ZXA_")
else
sRMBResult = "CommLog_Group_Say"
end
CallPlugin ("bfe35205f026786ea1d56e3b", "QuowSetTriggerOption", sRMBResult, "omit_from_output", "n")
else
objChatFilters[sRMBResult][3] = true
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Now hiding/not echoing '" .. sRMBResult .. "' from main MUD output.")
if (sRMBResult ~= "Group_Say") then
sRMBResult = "CommLog_" .. string.gsub(sRMBResult, "-", "_ZXA_")
else
sRMBResult = "CommLog_Group_Say"
end
CallPlugin ("bfe35205f026786ea1d56e3b", "QuowSetTriggerOption", sRMBResult, "omit_from_output", "y")
end
-- ******************************
-- * Group Shields menu options *
-- ******************************
elseif (sRMBResult == "Group Say Group Kills Report") then
local sGroupReport = ""
for sCharacterName, sGroupData in pairs(sGroupMembers) do
if (sCharacterName ~= "You") then
sGroupReport = sGroupReport .. sCharacterName .. ": " .. sGroupData["Kills"] .. " kills [~" .. string.format("%.0f", (sGroupData["Kills"] / ((os.time() - sGroupData["MemberSince"]) / 3600) )) .. " k/h] "
end
end
if (sGroupReport ~= "") then
Send("group say " .. sGroupReport)
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Unable to generate a group kills report. Try 'Refresh Group Status and Shields' first to make sure the plugin is logging your group stats.")
end
elseif (sRMBResult == "Show Private Group Kills Report") then
local bAnyReports = false
for sCharacterName, sGroupData in pairs(sGroupMembers) do
if (sCharacterName ~= "You") then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, sCharacterName, sGlobalColourSilver, sGlobalColourBlack, ": " .. sGroupData["Kills"] .. " kills. ~" .. string.format("%.0f", (sGroupData["Kills"] / ((os.time() - sGroupData["MemberSince"]) / 3600) )) .. " k/h. Member for " .. MinutesToTimeString(math.floor((os.time() - sGroupData["MemberSince"]) / 60)) .. ".")
bAnyReports = true
end
end
if (bAnyReports == false) then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Unable to generate a group kills report. Try 'Refresh Group Status and Shields' first to make sure the plugin is logging your group stats.")
end
elseif (sRMBResult == "Refresh Solo Character Shields") then
for sCharacterName, sGroupData in pairs(sGroupMembers) do
if (sCharacterName ~= "You") then
sGroupMembers[sCharacterName] = nil
end
end
RedrawShieldsWindow()
Redraw()
SendNoEcho("shields")
elseif (sRMBResult == "Refresh Group Status and Shields") then
for sCharacterName, sGroupData in pairs(sGroupMembers) do
if (sCharacterName ~= "You") then
sGroupMembers[sCharacterName] = nil
end
end
RedrawShieldsWindow()
Redraw()
SendNoEcho("group status brief")
SendNoEcho("group shields")
-- ******************************
-- * Vitals window menu options *
-- ******************************
elseif (sRMBResult == "Colour: HP Full Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_hp_a"], "vitals_hp_a")
elseif (sRMBResult == "Colour: HP Half Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_hp_b"], "vitals_hp_b")
elseif (sRMBResult == "Colour: HP Low Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_hp_c"], "vitals_hp_c")
elseif (sRMBResult == "Colour: GP Full Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_gp_a"], "vitals_gp_a")
elseif (sRMBResult == "Colour: GP Half Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_gp_b"], "vitals_gp_b")
elseif (sRMBResult == "Colour: GP Low Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_gp_c"], "vitals_gp_c")
elseif (sRMBResult == "Colour: Burden Empty Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_b_a"], "vitals_b_a")
elseif (sRMBResult == "Colour: Burden Half Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_b_b"], "vitals_b_b")
elseif (sRMBResult == "Colour: Burden Heavy Colour") then
FetchVitalsColour(sUSER_OPTIONS["vitals_b_c"], "vitals_b_c")
elseif (sRMBResult == "Show HP Loss Notification Texts") then
if (bShowHPNotifications == true) then
bShowHPNotifications = false
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar will not show any HP drop notices.")
else
bShowHPNotifications = true
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar will output a notice to your output window for all HP drops.")
end
elseif (sRMBResult == "Stack Bars Vertically") then
if (bVitalStacking == true) then
bVitalStacking = false
else
bVitalStacking = true
end
RedrawVitalsWindow()
Repaint()
elseif (sRMBResult == "Choose GP Full Wav File Sound") then
local sFilename = utils.filepicker("Select Valid *.Wav Nofication Sound", sGPNotificationFile, "*.wav", { ["wav"] = "Wav Files" }, false)
if (sFilename ~= nil) then
sGPNotificationFile = sFilename
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your GP full notification soundfile is now set to: '" .. sGPNotificationFile .. "'. Note that only valid format .wav files will actually play.")
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your GP full notification soundfile is unchanged.")
end
elseif (sRMBResult == "Play Sound On Full GP") then
if (bPlayGPNotification == true) then
bPlayGPNotification = false
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar will not play any notification sounds.")
else
SetOption ("play_sounds_in_background", 1)
bPlayGPNotification = true
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar will attempt to play a soundfile when your GP is full again, IF it has dropped to 75% full or less before refilling again.")
end
-- **************************
-- * XP window menu options *
-- **************************
elseif (sRMBResult == "Show XP Gain Notification Texts") then
if (bShowXPNotifications == true) then
bShowXPNotifications = false
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar will not show any XP gain notices.")
else
bShowXPNotifications = true
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar will output a notice to your output window for all XP gains over 1000.")
end
elseif (sRMBResult == "Reset XP Rate") then
iXPGraphPlots = {}
iXPTotalPlots = {}
iXPPerHour = 0
iXPTotalRecordedIncoming = 0
iXPMinutesRecordedTotal = 0
iXPTotalMinutePrevious = nil
iXPTotalMinuteCurrent = nil
iXPHighestPlot = 0
iXPPastHour = 0
RedrawXPWindow(true)
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Reset XP/Hour recording. New rate recording starting.")
elseif (sRMBResult == "Group Say XP Rate") then
Send("group say Current Hour XP Rate: " .. NumberCommaString(iXPPerHour) .. " XP/Hour. [" .. NumberCommaString(iXPTotalRecordedIncoming) .. " total XP in " .. MinutesToTimeString(iXPMinutesRecordedTotal) .. " " .. ((iXPMinutesRecordedTotal > 0) and NumberCommaString(math.floor((iXPTotalRecordedIncoming / iXPMinutesRecordedTotal) * 60)) or 0) .. " xp/h]")
elseif (sRMBResult == "Show XP Report") then
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " Character current XP: ", sGlobalColourOrange, sGlobalColourBlack, NumberCommaString(iCharVitals["xp"]) .. " xp")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " Total Time Recording: ", sGlobalColourOrange, sGlobalColourBlack, MinutesToTimeString(iXPMinutesRecordedTotal))
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " Total earned since reset: ", sGlobalColourOrange, sGlobalColourBlack, NumberCommaString(iXPTotalRecordedIncoming) .. " xp")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, " Total xp/h rate since reset: ", sGlobalColourOrange, sGlobalColourBlack, ((iXPMinutesRecordedTotal > 0) and NumberCommaString(math.floor((iXPTotalRecordedIncoming / iXPMinutesRecordedTotal) * 60)) or 0) .. " xp/h")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, string.format("%31s ", "Total earned past " .. ((iXPMinutesRecordedTotal >= 60) and MinutesToTimeString(60) or MinutesToTimeString(iXPMinutesRecordedTotal)) .. ":") .. " ", sGlobalColourOrange, sGlobalColourBlack, NumberCommaString(iXPPastHour) .. " xp")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, string.format("%31s ", "Current xp/h over past " .. ((iXPMinutesRecordedTotal >= 60) and MinutesToTimeString(60) or MinutesToTimeString(iXPMinutesRecordedTotal)) .. ":") .. " ", sGlobalColourOrange, sGlobalColourBlack, NumberCommaString(iXPPerHour) .. " xp/h")
-- ****************************
-- * Stat window menu options *
-- ****************************
elseif (sRMBResult == "Optimize Plugin Combat Triggers") then
if (bOptimisedCombatTriggers == false) then
if (iMushclientVersion >= 4.89) then
SendNoEcho("options colour combat=YELLOW")
bOptimisedCombatTriggers = true
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Setting your Discworld-side combat options to YELLOW.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This allows the plugin to optimize triggers for detecting combat messages accurately, and will reduce plugin overhead from non-combat lines from the MUD.")
ColourNote(sGlobalColourCyan, sGlobalColourBlack, "Important Note: If you have alts, their colour option will also need to be set, or the plugin will ignore combat messages received when playing on them.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "You can disable and re-enable this option once for each character to set their colours, or manually send 'options colour combat=YELLOW' on them once.")
EnableTrigger("QuowStatOptimizer", true)
else
ColourNote(sGlobalColourRed, sGlobalColourBlack, "Your MUSHclient is too old to support this optimization!")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Unfortunately, only MUSHclient versions from 4.89 and above can support this feature. You can upgrade from http://www.gammon.com.au/files/mushclient/?M=D")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "This optimization would prevent non-combat lines going through the large set of combat-stat related triggers, which helps reduce plugin overhead.")
end
else
bOptimisedCombatTriggers = false
SendNoEcho("options colour combat=WHITE")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Your Discworld-side combat colour option has been set to 'WHITE'.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "You can set it back to any colour you want with 'options colour combat=<colour>', if you wish to keep optimizations disabled.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "The optimizations are heavily recommended if you are not disabling the combat stats module of this plugin.")
EnableTrigger("QuowStatOptimizer", false)
end
elseif (sRMBResult == "Reset Current Set Stats") then
for sColumn, sData in pairs(iQuowCombatStats[iCurrentCombatStatSet]) do
if (sColumn ~= "set_name" and sColumn ~= "gp_regen") then
iQuowCombatStats[iCurrentCombatStatSet][sColumn] = 0
end
end
RedrawStatsWindow()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "All of your combat sets for the currently selected set '" .. iQuowCombatStats[iCurrentCombatStatSet]["set_name"] .. "' have been reset to 0.")
elseif (sRMBResult == "Rename Current Set") then
local sPopupResult = utils.inputbox("Enter a name for this combat stat set.\n\nIf it matches your player name and you have logon informs on, it will automatically be switched to on log-on.\n\nOr you could put 'frimble [<name> enters Discworld]' in your 'login' alias.\n", "Stat Set Rename", iQuowCombatStats[iCurrentCombatStatSet]["set_name"], "", 12)
if (sPopupResult ~= nil and sPopupResult ~= iQuowCombatStats[iCurrentCombatStatSet]["set_name"]) then
iQuowCombatStats[iCurrentCombatStatSet]["set_name"] = sPopupResult
RedrawStatsWindow()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "This combat set has been renamed to: '" .. sPopupResult .. "'")
else
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "The combat set name has not been changed.")
end
elseif (sRMBResult == "Generate Full Stat Report") then
GenerateStatsReport()
elseif (string.sub(sRMBResult, 1, 9) == "GP Regen ") then
sRMBResult = string.sub(sRMBResult, 10)
local iGPRegen = tonumber(sRMBResult)
if (iGPRegen < 0) then
iGPRegen = 0
elseif (iGPRegen > 4) then
iGPRegen = 4
end
if (iGPRegen ~= iQuowCombatStats[iCurrentCombatStatSet]["gp_regen"]) then
iQuowCombatStats[iCurrentCombatStatSet]["gp_regen"] = iGPRegen
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "The GP Regeneration rate of this set is now " .. iGPRegen .. " GP per heartbeat tick")
end
elseif (string.sub(sRMBResult, 1, 5) == "[Set " and string.find(sRMBResult, "]")) then
sRMBResult = string.sub(sRMBResult, 6, string.find(sRMBResult, "]") - 1)
-- Save current stats set to file before we switch
if (iCurrentCombatStatSet ~= 0) then
sSQL = "UPDATE combat_stats SET "
for sColumn, sData in pairs(iQuowCombatStats[iCurrentCombatStatSet]) do
if (sColumn ~= "set_name") then
sSQL = sSQL .. sColumn .. "=" .. sData .. ","
else
sSQL = sSQL .. sColumn .. "='" .. EscapeSQL(sData) .. "',"
end
end
sSQL = string.sub(sSQL, 1, -2)
sSQL = sSQL .. " WHERE set_id=" .. iCurrentCombatStatSet
assert(dbUserData:execute(sSQL))
end
iCurrentCombatStatSet = tonumber(sRMBResult)
RedrawStatsWindow()
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Switched your combat stats set to set " .. iCurrentCombatStatSet .. ": '" .. iQuowCombatStats[iCurrentCombatStatSet]["set_name"] .. "'")
elseif (sRMBResult == "Show message samples in output") then
ColourNote(iGlobalColourSilver, "", "Displaying sample combat trigger colours:")
ColourNote(iGlobalColourSilver, "", "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
ColourNote(sUSER_OPTIONS["col_special_prep"], "", "Sample: You prepare to stab the enemy with your weapon.")
ColourNote(sUSER_OPTIONS["col_special_fail"], "", "Sample: You attempt to stab the enemy but cannot find an opportunity.")
ColourNote(sUSER_OPTIONS["col_special_out_fail"], "", "Sample: You attempt to launch a powerful attack, but the enemy parries the blow.")
ColourNote(sUSER_OPTIONS["col_special_out_success"], "", "Sample: You launch a powerful attack and stab the enemy deeply with your weapon.")
ColourNote(sUSER_OPTIONS["col_melee_out_fail"], "", "Sample: You cut at the enemy but they parry the blow.")
ColourNote(sUSER_OPTIONS["col_melee_out_success"], "", "Sample: You slash the enemy in the face with your weapon.")
ColourNote(sUSER_OPTIONS["col_melee_out_kill"], "", "Sample: You kill the enemy.")
ColourNote(sUSER_OPTIONS["col_special_inc_fail"], "", "Sample: Enemy attempts to launch a powerful attack, but you dodge out of the way.")
ColourNote(sUSER_OPTIONS["col_special_inc_success"], "", "Sample: Enemy launches a powerful attack and stabs you deeply with their weapon.")
ColourNote(sUSER_OPTIONS["col_melee_inc_fail"], "", "Sample: Enemy cuts at you, but you dodge out of the way.")
ColourNote(sUSER_OPTIONS["col_melee_inc_success"], "", "Sample: Enemy stabs you in the arm with their weapon.")
ColourNote(sUSER_OPTIONS["col_melee_inc_kill"], "", "Sample: Enemy deals the death blow to you.")
ColourNote(sUSER_OPTIONS["col_special_third_fail"], "", "Sample: The cow attempts to launch a powerful attack but the sheep frolics out of the way.")
ColourNote(sUSER_OPTIONS["col_special_third_success"], "","Sample: The cow launches a powerful attack and mashes the sheep's skull in.")
ColourNote(sUSER_OPTIONS["col_melee_third_fail"], "", "Sample: The cow strikes at the sheep with a hoof, but it somehow avoids the attack.")
ColourNote(sUSER_OPTIONS["col_melee_third_success"], "", "Sample: The cow crushes the sheep with it's hoofies.")
ColourNote(sUSER_OPTIONS["col_melee_third_kill"], "", "Sample: The cow kills the sheep.")
-- Hiding text choices:
elseif (sRMBResult == "Show: You prepare a special") then
sUSER_OPTIONS["omit_special_prep"] = ((sUSER_OPTIONS["omit_special_prep"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_prep"]) .. "' WHERE option_id='omit_special_prep'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: You fail to prepare a special") then
sUSER_OPTIONS["omit_special_fail"] = ((sUSER_OPTIONS["omit_special_fail"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_fail"]) .. "' WHERE option_id='omit_special_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: You special enemy but they defend") then
sUSER_OPTIONS["omit_special_out_fail"] = ((sUSER_OPTIONS["omit_special_out_fail"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_out_fail"]) .. "' WHERE option_id='omit_special_out_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: You special and hurt enemy") then
sUSER_OPTIONS["omit_special_out_success"] = ((sUSER_OPTIONS["omit_special_out_success"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_out_success"]) .. "' WHERE option_id='omit_special_out_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: You hit enemy but they defend") then
sUSER_OPTIONS["omit_melee_out_fail"] = ((sUSER_OPTIONS["omit_melee_out_fail"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_out_fail"]) .. "' WHERE option_id='omit_melee_out_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: You hit and hurt enemy") then
sUSER_OPTIONS["omit_melee_out_success"] = ((sUSER_OPTIONS["omit_melee_out_success"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_out_success"]) .. "' WHERE option_id='omit_melee_out_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: You kill enemy") then
sUSER_OPTIONS["omit_melee_out_kill"] = ((sUSER_OPTIONS["omit_melee_out_kill"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_out_kill"]) .. "' WHERE option_id='omit_melee_out_kill'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Enemy specials you but you defend") then
sUSER_OPTIONS["omit_special_inc_fail"] = ((sUSER_OPTIONS["omit_special_inc_fail"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_inc_fail"]) .. "' WHERE option_id='omit_special_inc_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Enemy specials and hurts you") then
sUSER_OPTIONS["omit_special_inc_success"] = ((sUSER_OPTIONS["omit_special_inc_success"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_inc_success"]) .. "' WHERE option_id='omit_special_inc_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Enemy hits you but you defend") then
sUSER_OPTIONS["omit_melee_inc_fail"] = ((sUSER_OPTIONS["omit_melee_inc_fail"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_inc_fail"]) .. "' WHERE option_id='omit_melee_inc_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Enemy hits and hurts you") then
sUSER_OPTIONS["omit_melee_inc_success"] = ((sUSER_OPTIONS["omit_melee_inc_success"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_inc_success"]) .. "' WHERE option_id='omit_melee_inc_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Enemy kills you") then
sUSER_OPTIONS["omit_melee_inc_kill"] = ((sUSER_OPTIONS["omit_melee_inc_kill"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_inc_kill"]) .. "' WHERE option_id='omit_melee_inc_kill'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Others special others who defend") then
sUSER_OPTIONS["omit_special_third_fail"] = ((sUSER_OPTIONS["omit_special_third_fail"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_third_fail"]) .. "' WHERE option_id='omit_special_third_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Others special and hurt others") then
sUSER_OPTIONS["omit_special_third_success"] = ((sUSER_OPTIONS["omit_special_third_success"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_special_third_success"]) .. "' WHERE option_id='omit_special_third_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Others hit others who defend") then
sUSER_OPTIONS["omit_melee_third_fail"] = ((sUSER_OPTIONS["omit_melee_third_fail"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_third_fail"]) .. "' WHERE option_id='omit_melee_third_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Others hit and hurt others") then
sUSER_OPTIONS["omit_melee_third_success"] = ((sUSER_OPTIONS["omit_melee_third_success"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_third_success"]) .. "' WHERE option_id='omit_melee_third_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
elseif (sRMBResult == "Show: Others kill others") then
sUSER_OPTIONS["omit_melee_third_kill"] = ((sUSER_OPTIONS["omit_melee_third_kill"] ~= "y") and "y" or "n")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["omit_melee_third_kill"]) .. "' WHERE option_id='omit_melee_third_kill'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
-- Don't custom colour these lines
elseif (sRMBResult == "Re-Colour: You prepare a special") then
sUSER_OPTIONS["nocol_special_prep"] = ((sUSER_OPTIONS["nocol_special_prep"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_prep"]) .. "' WHERE option_id='nocol_special_prep'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: You fail to prepare a special") then
sUSER_OPTIONS["nocol_special_fail"] = ((sUSER_OPTIONS["nocol_special_fail"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_fail"]) .. "' WHERE option_id='nocol_special_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: You special enemy but they defend") then
sUSER_OPTIONS["nocol_special_out_fail"] = ((sUSER_OPTIONS["nocol_special_out_fail"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_out_fail"]) .. "' WHERE option_id='nocol_special_out_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: You special and hurt enemy") then
sUSER_OPTIONS["nocol_special_out_success"] = ((sUSER_OPTIONS["nocol_special_out_success"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_out_success"]) .. "' WHERE option_id='nocol_special_out_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: You hit enemy but they defend") then
sUSER_OPTIONS["nocol_melee_out_fail"] = ((sUSER_OPTIONS["nocol_melee_out_fail"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_out_fail"]) .. "' WHERE option_id='nocol_melee_out_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: You hit and hurt enemy") then
sUSER_OPTIONS["nocol_melee_out_success"] = ((sUSER_OPTIONS["nocol_melee_out_success"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_out_success"]) .. "' WHERE option_id='nocol_melee_out_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: You kill enemy") then
sUSER_OPTIONS["nocol_melee_out_kill"] = ((sUSER_OPTIONS["nocol_melee_out_kill"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_out_kill"]) .. "' WHERE option_id='nocol_melee_out_kill'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Enemy specials you but you defend") then
sUSER_OPTIONS["nocol_special_inc_fail"] = ((sUSER_OPTIONS["nocol_special_inc_fail"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_inc_fail"]) .. "' WHERE option_id='nocol_special_inc_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Enemy specials and hurts you") then
sUSER_OPTIONS["nocol_special_inc_success"] = ((sUSER_OPTIONS["nocol_special_inc_success"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_inc_success"]) .. "' WHERE option_id='nocol_special_inc_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Enemy hits you but you defend") then
sUSER_OPTIONS["nocol_melee_inc_fail"] = ((sUSER_OPTIONS["nocol_melee_inc_fail"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_inc_fail"]) .. "' WHERE option_id='nocol_melee_inc_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Enemy hits and hurts you") then
sUSER_OPTIONS["nocol_melee_inc_success"] = ((sUSER_OPTIONS["nocol_melee_inc_success"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_inc_success"]) .. "' WHERE option_id='nocol_melee_inc_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Enemy kills you") then
sUSER_OPTIONS["nocol_melee_inc_kill"] = ((sUSER_OPTIONS["nocol_melee_inc_kill"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_inc_kill"]) .. "' WHERE option_id='nocol_melee_inc_kill'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Others special others who defend") then
sUSER_OPTIONS["nocol_special_third_fail"] = ((sUSER_OPTIONS["nocol_special_third_fail"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_third_fail"]) .. "' WHERE option_id='nocol_special_third_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Others special and hurt others") then
sUSER_OPTIONS["nocol_special_third_success"] = ((sUSER_OPTIONS["nocol_special_third_success"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_special_third_success"]) .. "' WHERE option_id='nocol_special_third_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Others hit others who defend") then
sUSER_OPTIONS["nocol_melee_third_fail"] = ((sUSER_OPTIONS["nocol_melee_third_fail"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_third_fail"]) .. "' WHERE option_id='nocol_melee_third_fail'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Others hit and hurt others") then
sUSER_OPTIONS["nocol_melee_third_success"] = ((sUSER_OPTIONS["nocol_melee_third_success"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_third_success"]) .. "' WHERE option_id='nocol_melee_third_success'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
elseif (sRMBResult == "Re-Colour: Others kill others") then
sUSER_OPTIONS["nocol_melee_third_kill"] = ((sUSER_OPTIONS["nocol_melee_third_kill"] == "17") and "0" or "17")
assert(dbUserData:execute("UPDATE user_options SET option_value='" .. tostring(sUSER_OPTIONS["nocol_melee_third_kill"]) .. "' WHERE option_id='nocol_melee_third_kill'"))
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersNoColour", "", "")
-- Re-colouring text choices:
elseif (sRMBResult == "Pick Colour: You prepare a special") then
sColourOption = "col_special_prep"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: You fail to prepare a special") then
sColourOption = "col_special_fail"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: You special enemy but they defend") then
sColourOption = "col_special_out_fail"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: You special and hurt enemy") then
sColourOption = "col_special_out_success"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: You hit enemy but they defend") then
sColourOption = "col_melee_out_fail"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: You hit and hurt enemy") then
sColourOption = "col_melee_out_success"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: You kill enemy") then
sColourOption = "col_melee_out_kill"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Enemy specials you but you defend") then
sColourOption = "col_special_inc_fail"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Enemy specials and hurts you") then
sColourOption = "col_special_inc_success"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Enemy hits you but you defend") then
sColourOption = "col_melee_inc_fail"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Enemy hits and hurts you") then
sColourOption = "col_melee_inc_success"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Enemy kills you") then
sColourOption = "col_melee_inc_kill"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Others special others who defend") then
sColourOption = "col_special_third_fail"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Others special and hurt others") then
sColourOption = "col_special_third_success"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Others hit others who defend") then
sColourOption = "col_melee_third_fail"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Others hit and hurt others") then
sColourOption = "col_melee_third_success"
FetchTriggerColour(sColourOption)
elseif (sRMBResult == "Pick Colour: Others kill others") then
sColourOption = "col_melee_third_kill"
FetchTriggerColour(sColourOption)
-- *************************************
-- * Global screen margin menu options *
-- *************************************
elseif (sRMBResult == "Lock Screen Margins") then
if (bLockMargins == true) then
Note("Screen margins are unlocked, you can now click-drag to resize your screen areas.")
bLockMargins = false
WindowShow(winScreenMarginLeft, true)
WindowShow(winScreenMarginTop, true)
WindowShow(winScreenMarginRight, true)
WindowShow(winScreenMarginBottom, true)
else
Note("Screen margins are now locked in place.")
bLockMargins = true
WindowShow(winScreenMarginLeft, false)
WindowShow(winScreenMarginTop, false)
WindowShow(winScreenMarginRight, false)
WindowShow(winScreenMarginBottom, false)
end
elseif (sRMBResult == "Left Edge Margin") then
if (SCREENMARGINS["left"][1] == true) then
SCREENMARGINS["left"][1] = false
WindowShow(winScreenMarginLeft, false)
else
SCREENMARGINS["left"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginLeft, true)
end
end
RedoScreenMargins()
elseif (sRMBResult == "Top Edge Margin") then
if (SCREENMARGINS["top"][1] == true) then
SCREENMARGINS["top"][1] = false
WindowShow(winScreenMarginTop, false)
else
SCREENMARGINS["top"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginTop, true)
end
end
RedoScreenMargins()
elseif (sRMBResult == "Right Edge Margin") then
if (SCREENMARGINS["right"][1] == true) then
SCREENMARGINS["right"][1] = false
WindowShow(winScreenMarginRight, false)
else
SCREENMARGINS["right"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginRight, true)
end
end
RedoScreenMargins()
elseif (sRMBResult == "Bottom Edge Margin") then
if (SCREENMARGINS["bottom"][1] == true) then
SCREENMARGINS["bottom"][1] = false
WindowShow(winScreenMarginBottom, false)
else
SCREENMARGINS["bottom"][1] = true
if (bLockMargins == false) then
WindowShow(winScreenMarginBottom, true)
end
end
RedoScreenMargins()
end
end
end
end
end
-- For showing a window again after clicking a hyperlink
function QuowShowWindow(winShowWindow)
if (WINDATA[winShowWindow]["SHOW"] == false) then
WINDATA[winShowWindow]["SHOW"] = true
WindowShow(winShowWindow, true)
if (winShowWindow == winXP) then
RedrawXPWindow(true)
elseif (winShowWindow == winBars) then
RedrawVitalsWindow()
elseif (winShowWindow == winMDT) then
RedrawMDTWindow()
elseif (winShowWindow == winStats) then
RedrawStatsWindow()
elseif (winShowWindow == winShields) then
RedrawShieldsWindow()
elseif (winShowWindow == winComms) then
RedrawCommsWindow()
elseif (winShowWindow == winAscii) then
RedrawAsciiWindow()
elseif (winShowWindow == winAscii) then
RedrawMap()
end
Repaint()
end
end
-- For remote function calls on trigger changes
function QuowSetTriggerOption(sTriggerName, sOptionName, sOptionValue)
SetTriggerOption(sTriggerName, sOptionName, sOptionValue)
end
function QuowAddTalkerTrigger(sChannelName)
local sThisTrigger = "CommLog_" .. string.gsub(sChannelName, "-", "_ZXA_")
AddTriggerEx(sThisTrigger, "^(?:> )?\\((?P<channel>" .. string.gsub(sChannelName, "_", " ") .. ")\\) [A-Za-z](?:\\w+\\b\\W*?){1,8}", "", 33, -1, 0, "", "HandleCommsMessage", 12, 4)
SetTriggerOption(sThisTrigger, "group", "module_comms")
end
function QuowDeleteTalkerTrigger(sChannelName)
local sThisTrigger = "CommLog_" .. string.gsub(sChannelName, "-", "_ZXA_")
DeleteTrigger(sThisTrigger)
end
-- Re-do the screen margins
function RedoScreenMargins()
local iTopMargin = 0
local iLeftMargin = 0
local iRightMargin = 0
local iBottomMargin = 0
if (SCREENMARGINS["top"][1] == true) then
iTopMargin = SCREENMARGINS["top"][2]
end
if (SCREENMARGINS["left"][1] == true) then
iLeftMargin = SCREENMARGINS["left"][2]
end
if (SCREENMARGINS["right"][1] == true) then
iRightMargin = SCREENMARGINS["right"][2]
end
if (SCREENMARGINS["bottom"][1] == true) then
iBottomMargin = SCREENMARGINS["bottom"][2]
end
TextRectangle(iLeftMargin, iTopMargin, GetInfo(281) - iRightMargin, GetInfo(280) - iBottomMargin, 1, 0, 0, 0, 0)
Redraw()
end
-- Re-order the z-indices of the windows but make the given one on top
function ReorderWindows(winMakeThisTop)
for sKey, sData in pairs(WINDATA) do
if (sKey == winMakeThisTop) then
WindowSetZOrder(sKey, 20)
else
WindowSetZOrder(sKey, 15)
end
end
Redraw()
end
winScreenMarginLeft = GetPluginID() .. "_margin_l"
winScreenMarginTop = GetPluginID() .. "_margin_t"
winScreenMarginRight = GetPluginID() .. "_margin_r"
winScreenMarginBottom = GetPluginID() .. "_margin_b"
function OnPluginInstall()
-- Screen margin "windows" for live-resizing the margin
WindowCreate(winScreenMarginLeft, SCREENMARGINS["left"][2] - 4, 0, 4, GetInfo(280), 0, 2, winThemeData.WINDOW_BORDER)
WindowCreate(winScreenMarginTop, 0, SCREENMARGINS["top"][2] - 4, GetInfo(281), 4, 0, 2, winThemeData.WINDOW_BORDER)
WindowCreate(winScreenMarginRight, (GetInfo(281) - SCREENMARGINS["right"][2]), 0, 4, GetInfo(280), 0, 2, winThemeData.WINDOW_BORDER)
WindowCreate(winScreenMarginBottom, 0, (GetInfo(280) - SCREENMARGINS["bottom"][2]), GetInfo(281), 4, 0, 2, winThemeData.WINDOW_BORDER)
WindowAddHotspot(winScreenMarginLeft, "hsMarginL", 0, 0, 4, WindowInfo(winScreenMarginLeft, 4), "", "", "ResizeMarginMouseDown", "", "", "", miniwin.cursor_ew_arrow , 0)
WindowDragHandler(winScreenMarginLeft, "hsMarginL", "ResizeMarginCallback", "", 0)
WindowAddHotspot(winScreenMarginTop, "hsMarginT", 0, 0, WindowInfo(winScreenMarginTop, 3), 4, "", "", "ResizeMarginMouseDown", "", "", "", miniwin.cursor_ns_arrow , 0)
WindowDragHandler(winScreenMarginTop, "hsMarginT", "ResizeMarginCallback", "", 0)
WindowAddHotspot(winScreenMarginRight, "hsMarginR", 0, 0, 4, WindowInfo(winScreenMarginRight, 4), "", "", "ResizeMarginMouseDown", "", "", "", miniwin.cursor_ew_arrow , 0)
WindowDragHandler(winScreenMarginRight, "hsMarginR", "ResizeMarginCallback", "", 0)
WindowAddHotspot(winScreenMarginBottom, "hsMarginB", 0, 0, WindowInfo(winScreenMarginBottom, 3), 4, "", "", "ResizeMarginMouseDown", "", "", "", miniwin.cursor_ns_arrow , 0)
WindowDragHandler(winScreenMarginBottom, "hsMarginB", "ResizeMarginCallback", "", 0)
if (bLockMargins == false) then
if (SCREENMARGINS["left"][1] == true) then
WindowShow(winScreenMarginLeft, true)
else
WindowShow(winScreenMarginLeft, false)
end
if (SCREENMARGINS["top"][1] == true) then
WindowShow(winScreenMarginTop, true)
else
WindowShow(winScreenMarginTop, false)
end
if (SCREENMARGINS["right"][1] == true) then
WindowShow(winScreenMarginRight, true)
else
WindowShow(winScreenMarginRight, false)
end
if (SCREENMARGINS["bottom"][1] == true) then
WindowShow(winScreenMarginBottom, true)
else
WindowShow(winScreenMarginBottom, false)
end
end
if (bShowCommsTabs == true) then
iTopCommsWindow = winThemeData.TITLE_HEIGHT
else
iTopCommsWindow = 0
end
-- Prepare the minimap window
winInfoMinimap = movewindow.install (winMinimap, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoMinimap.mouseup = MakeMouseupHandler(winMinimap)
-- Prepare the MDT window
winInfoMDT = movewindow.install (winMDT, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoMDT.mouseup = MakeMouseupHandler(winMDT)
-- Prepare the character vitals window
winInfoBars = movewindow.install (winBars, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoBars.mouseup = MakeMouseupHandler(winBars)
-- Prepare the XP window
winInfoXP = movewindow.install (winXP, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoXP.mouseup = MakeMouseupHandler(winXP)
-- Prepare the combat-related stats window
winInfoStats = movewindow.install (winStats, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoStats.mouseup = MakeMouseupHandler(winStats)
-- Prepare the Shields window
winInfoShields = movewindow.install (winShields, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoShields.mouseup = MakeMouseupHandler(winShields)
-- Prepare the Comms window
winInfoComms = movewindow.install (winComms, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoComms.mouseup = MakeMouseupHandler(winComms)
-- Prepare the Ascii-Map window
winInfoAscii = movewindow.install (winAscii, miniwin.pos_top_right, miniwin.create_absolute_location, true, {["x"] = GetInfo(272), ["y"] = 1})
-- Replace the movewindow mouseup function with mine
winInfoAscii.mouseup = MakeMouseupHandler(winAscii)
-- Now actually CREATE the windows
-- Main minimap window
WindowCreate(winMinimap, winInfoMinimap.window_left, winInfoMinimap.window_top, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], winInfoMinimap.window_mode, winInfoMinimap.window_flags, iGlobalColourBlack)
-- And a drag handler in the titlebar
movewindow.add_drag_handler(winMinimap, 0, 0, WINDATA[winMinimap]["WIDTH"], winThemeData.TITLE_HEIGHT)
-- MDT Map-Door-Text window
WindowCreate(winMDT, winInfoMDT.window_left, winInfoMDT.window_top, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"], winInfoMDT.window_mode, winInfoMDT.window_flags, iGlobalColourBlack)
-- Drag handler in the entire window zone
movewindow.add_drag_handler(winMDT, 0, 0, WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"])
-- Bars window
WindowCreate(winBars, winInfoBars.window_left, winInfoBars.window_top, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"], winInfoBars.window_mode, winInfoBars.window_flags, iGlobalColourBlack)
-- Drag handler in the entire window zone
movewindow.add_drag_handler(winBars, 0, 0, WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"])
-- XP window
WindowCreate(winXP, winInfoXP.window_left, winInfoXP.window_top, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"], winInfoXP.window_mode, winInfoXP.window_flags, iGlobalColourBlack)
-- Drag handler in the entire window zone
movewindow.add_drag_handler(winXP, 0, 0, WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"])
-- Stats window
WindowCreate(winStats, winInfoStats.window_left, winInfoStats.window_top, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"], winInfoStats.window_mode, winInfoStats.window_flags, iGlobalColourBlack)
-- Drag handler in the entire window zone
movewindow.add_drag_handler(winStats, 0, 0, WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"])
-- Shields window
WindowCreate(winShields, winInfoShields.window_left, winInfoShields.window_top, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"], winInfoShields.window_mode, winInfoShields.window_flags, iGlobalColourBlack)
-- Drag handler in the entire window zone
movewindow.add_drag_handler(winShields, 0, 0, WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"])
-- Comms window
WindowCreate(winComms, winInfoComms.window_left, winInfoComms.window_top, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"], winInfoComms.window_mode, winInfoComms.window_flags, iGlobalColourBlack)
-- Drag handler in the entire window zone
movewindow.add_drag_handler(winComms, 0, iTopCommsWindow, WINDATA[winComms]["WIDTH"] - SCROLL_BAR_WIDTH, WINDATA[winComms]["HEIGHT"])
-- Ascii-Map window
WindowCreate(winAscii, winInfoAscii.window_left, winInfoAscii.window_top, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"], winInfoAscii.window_mode, winInfoAscii.window_flags, iGlobalColourBlack)
-- Drag handler in the entire window zone
movewindow.add_drag_handler(winAscii, 0, 0, WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"])
WindowFont(winMinimap, "bodyfont"..winMinimap, sUserFont, iFontSize)
WindowFont(winMDT, "bodyfont"..winMDT, sUserFont, iFontSize)
WindowFont(winComms, "bodyfont"..winComms, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii.."m", sUserFont, iFontSize + 2)
WindowFont(winAscii, "bodyfont"..winAscii.."l", sUserFont, iFontSize + 4)
WindowFont(winMinimap, "titlefont"..winMinimap, winThemeData.TITLE_FONT_NAME, winThemeData.TITLE_FONT_SIZE)
WindowFont(winBars, "bodyfont"..winBars, "Dina", 9)
WindowFont(winBars, "bodyfont"..winBars.."m", "Dina", 12)
WindowFont(winBars, "bodyfont"..winBars.."l", "Dina", 15)
WindowFont(winStats, "bodyfont"..winStats, "Dina", 8)
WindowFont(winStats, "bodyfont"..winStats.."m", "Dina", 11)
WindowFont(winStats, "bodyfont"..winStats.."l", "Dina", 14)
WindowFont(winXP, "bodyfont"..winXP, "Dina", 9)
WindowFont(winXP, "bodyfont"..winXP.."m", "Dina", 12)
WindowFont(winXP, "bodyfont"..winXP.."l", "Dina", 15)
WindowFont(winShields, "bodyfont"..winShields, "Dina", 8, true)
WindowFont(winShields, "bodyfont"..winShields.."m", "Dina", 11, true)
WindowFont(winShields, "bodyfont"..winShields.."l", "Dina", 14, true)
WindowFont(winComms, "bodyfont"..winComms, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii, sUserFont, iFontSize)
WindowFont(winAscii, "bodyfont"..winAscii.."m", sUserFont, iFontSize + 2)
WindowFont(winAscii, "bodyfont"..winAscii.."l", sUserFont, iFontSize + 4)
-- Gather font-size data
iGlobalFontHeight = WindowFontInfo(winMinimap, "bodyfont"..winMinimap, 1) - WindowFontInfo(winMinimap, "bodyfont"..winMinimap, 4) + 1
iGlobalLineHeight = iGlobalFontHeight + 1
iGlobalFontWidth = WindowTextWidth(winMinimap, "bodyfont"..winMinimap, "W")
-- Main clicky map area
WindowAddHotspot(winMinimap, "hsMapClick", 4, winThemeData.TITLE_HEIGHT, WINDATA[winMinimap]["WIDTH"] - 4, WINDATA[winMinimap]["HEIGHT"] - 4, "", "", "", "", "QuowMapMouse", "Click on a room, then right-click for options", miniwin.cursor_plus)
-- Create the draggable edges for all the windows window
CreateResizableWindow(winMinimap, "Map", WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
CreateResizableWindow(winMDT, "MDT", WINDATA[winMDT]["WIDTH"], WINDATA[winMDT]["HEIGHT"])
CreateResizableWindow(winBars, "Bar", WINDATA[winBars]["WIDTH"], WINDATA[winBars]["HEIGHT"])
CreateResizableWindow(winXP, "XP", WINDATA[winXP]["WIDTH"], WINDATA[winXP]["HEIGHT"])
CreateResizableWindow(winStats, "Stats", WINDATA[winStats]["WIDTH"], WINDATA[winStats]["HEIGHT"])
CreateResizableWindow(winShields, "Shields", WINDATA[winShields]["WIDTH"], WINDATA[winShields]["HEIGHT"])
CreateResizableWindow(winComms, "Comms", WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"])
CreateResizableWindow(winAscii, "Ascii", WINDATA[winAscii]["WIDTH"], WINDATA[winAscii]["HEIGHT"])
WindowAddHotspot(winComms, "hsCommsUp", WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH + 1), iTopCommsWindow, WINDATA[winComms]["WIDTH"]-1, SCROLL_BAR_WIDTH + iTopCommsWindow,
"", "", "CommsMouseDown", "", "CommsMouseUp", "", miniwin.cursor_hand, 0)
WindowAddHotspot(winComms, "hsCommsDown", WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH + 1), WINDATA[winComms]["HEIGHT"]-(SCROLL_BAR_WIDTH), WINDATA[winComms]["WIDTH"]-1, WINDATA[winComms]["HEIGHT"]-1,
"", "", "CommsMouseDown", "", "CommsMouseUp", "", miniwin.cursor_hand, 0)
WindowAddHotspot(winComms, "hsCommScroller", WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH + 1), SCROLL_BAR_WIDTH, WINDATA[winComms]["WIDTH"] - 1, WINDATA[winComms]["HEIGHT"]-SCROLL_BAR_WIDTH,
"", "", "CommsMouseDown", "", "CommsMouseUp", "", miniwin.cursor_hand, 0)
if (bShowCommsTabs == true) then
WindowAddHotspot(winComms, "hsChatTabs", 0, 0, WINDATA[winComms]["WIDTH"], iTopCommsWindow, "", "", "", "", "ChatTabMouseUp", "", miniwin.cursor_hand, 0)
end
WindowDragHandler(winComms, "hsCommScroller", "ScrollerMoveCallback", "ScrollerReleaseCallback", 0)
-- Set up some quick-lookup variables for speed elsewhere
MINIMAP_WIDTH=WINDATA[winMinimap]["WIDTH"]
MINIMAP_HEIGHT=WINDATA[winMinimap]["HEIGHT"]-winThemeData.TITLE_HEIGHT
MINIMAP_X = 0
MINIMAP_Y = winThemeData.TITLE_HEIGHT
MINIMAP_CX = math.floor(MINIMAP_WIDTH/2)
MINIMAP_CY = math.floor(MINIMAP_HEIGHT/2)+winThemeData.TITLE_HEIGHT
-- Re-order the z-indices
ReorderWindows(winMinimap)
-- Build regexes and colours
CombatRegexBuilder()
TriggersRecolour()
TriggersShowHide()
TriggersNoColour()
if (bOptimisedCombatTriggers == true and iMushclientVersion >= 4.89) then
EnableTrigger("QuowStatOptimizer", true)
end
-- And finally call the on-plugin-enable function to re-display windows on-screen (draw them)
OnPluginEnable()
iOldTextRectangleData[1] = GetInfo(272)
iOldTextRectangleData[2] = GetInfo(273)
iOldTextRectangleData[3] = GetInfo(274)
iOldTextRectangleData[4] = GetInfo(275)
-- Special case backup to prevent Mushclient crashing from trying to spam-redraw the screen on initial Mushclient launch
if (GetInfo(106) == false) then
bPreInstalled = true
RedoScreenMargins()
else
DoAfterSpecial (5, "OnPluginConnect()", sendto.script)
end
-- First ever run check
if (GetVariable("EverRunv2") == nil) then
if (iThemeLayoutLocked ~= 11) then
QuowLayoutTheme(2)
else
QuowLayoutTheme(11)
end
SetVariable("EverRunv2", "Yes")
end
-- Force-disable unwanted modules
if (MODULES["vitals"] == false) then
WINDATA[winBars]["SHOW"] = false
WindowShow(winBars, false)
EnableTriggerGroup ("module_vitals", false)
EnableTimer("timer_gpregen", false)
end
if (MODULES["xp"] == false) then
WINDATA[winXP]["SHOW"] = false
WindowShow(winXP, false)
EnableTriggerGroup ("module_xp", false)
EnableTimer("timer_xpgraph", false)
end
if (MODULES["mdt"] == false) then
WINDATA[winMDT]["SHOW"] = false
WindowShow(winMDT, false)
EnableTriggerGroup ("module_mdt", false)
end
if (MODULES["ascii"] == false) then
WINDATA[winAscii]["SHOW"] = false
WindowShow(winAscii, false)
EnableTriggerGroup ("module_ascii", false)
end
if (MODULES["stats"] == false) then
WINDATA[winStats]["SHOW"] = false
WindowShow(winStats, false)
EnableTriggerGroup ("module_stats", false)
end
if (MODULES["shields"] == false) then
WINDATA[winShields]["SHOW"] = false
WindowShow(winShields, false)
EnableTriggerGroup ("module_shields", false)
end
if (MODULES["comms"] == false) then
WINDATA[winComms]["SHOW"] = false
WindowShow(winComms, false)
sCommsBuffer = {}
EnableTriggerGroup ("module_comms", false)
end
end -- function OnPluginInstall
-- Backup to prevent screen redraws while Mushclient is loading
function OnPluginConnect()
bPreInstalled = true
RedoScreenMargins()
end -- function
-- Quow's functions to create draggable, resizable, window edges in a modular way!
function CreateResizableWindow(winThisResizer, sShorthand, iThisWinWidth, iThisWinHeight)
-- Resize hotspot left
WindowAddHotspot(winThisResizer, "hsLResizer" .. sShorthand, 0, winThemeData.TITLE_HEIGHT, 4, iThisWinHeight - 20, "", "", "ResizeWindowMouseDown", "", "", "", miniwin.cursor_ew_arrow, 0)
-- Resize hotspot bottomleft
WindowAddHotspot(winThisResizer, "hsBL1Resizer" .. sShorthand, 0, iThisWinHeight - 20, 4, iThisWinHeight, "", "", "ResizeWindowMouseDown", "", "", "", miniwin.cursor_ne_sw_arrow , 0)
WindowAddHotspot(winThisResizer, "hsBL2Resizer" .. sShorthand, 4, iThisWinHeight - 4, 20, iThisWinHeight, "", "", "ResizeWindowMouseDown", "", "", "", miniwin.cursor_ne_sw_arrow , 0)
-- Resize hotspot right
WindowAddHotspot(winThisResizer, "hsRResizer" .. sShorthand, iThisWinWidth - 4, winThemeData.TITLE_HEIGHT, iThisWinWidth, iThisWinHeight - 20, "", "", "ResizeWindowMouseDown", "", "", "", miniwin.cursor_ew_arrow, 0)
-- Resize hotspot bottomright
WindowAddHotspot(winThisResizer, "hsBR1Resizer" .. sShorthand, iThisWinWidth - 4, iThisWinHeight - 20, iThisWinWidth, iThisWinHeight, "", "", "ResizeWindowMouseDown", "", "", "", miniwin.cursor_nw_se_arrow , 0)
WindowAddHotspot(winThisResizer, "hsBR2Resizer" .. sShorthand, iThisWinWidth - 20, iThisWinHeight - 4, iThisWinWidth - 4, iThisWinHeight, "", "", "ResizeWindowMouseDown", "", "", "", miniwin.cursor_nw_se_arrow , 0)
-- Resize hotspot bottom
WindowAddHotspot(winThisResizer, "hsBResizer" .. sShorthand, 20, iThisWinHeight - 4, iThisWinWidth - 20, iThisWinHeight, "", "", "ResizeWindowMouseDown", "", "", "", miniwin.cursor_ns_arrow , 0)
-- Drag handlers for the 7 points
WindowDragHandler(winThisResizer, "hsLResizer" .. sShorthand, "ResizeMoveCallback", "", 0)
WindowDragHandler(winThisResizer, "hsBL1Resizer" .. sShorthand, "ResizeMoveCallback", "", 0)
WindowDragHandler(winThisResizer, "hsBL2Resizer" .. sShorthand, "ResizeMoveCallback", "", 0)
WindowDragHandler(winThisResizer, "hsRResizer" .. sShorthand, "ResizeMoveCallback", "", 0)
WindowDragHandler(winThisResizer, "hsBR1Resizer" .. sShorthand, "ResizeMoveCallback", "", 0)
WindowDragHandler(winThisResizer, "hsBR2Resizer" .. sShorthand, "ResizeMoveCallback", "", 0)
WindowDragHandler(winThisResizer, "hsBResizer" .. sShorthand, "ResizeMoveCallback", "", 0)
end
-- And this is to update all of those resizable hot-edges for when the window size is changed
function UpdateResizableWindow(winThisResizer, sShorthand, iThisWinWidth, iThisWinHeight)
WindowMoveHotspot(winThisResizer, "hsLResizer" .. sShorthand, 0, winThemeData.TITLE_HEIGHT, 4, iThisWinHeight - 20)
WindowMoveHotspot(winThisResizer, "hsBL1Resizer" .. sShorthand, 0, iThisWinHeight - 20, 4, iThisWinHeight)
WindowMoveHotspot(winThisResizer, "hsBL2Resizer" .. sShorthand, 4, iThisWinHeight - 4, 20, iThisWinHeight)
WindowMoveHotspot(winThisResizer, "hsRResizer" .. sShorthand, iThisWinWidth - 4, winThemeData.TITLE_HEIGHT, iThisWinWidth, iThisWinHeight - 20)
WindowMoveHotspot(winThisResizer, "hsBR1Resizer" .. sShorthand, iThisWinWidth - 4, iThisWinHeight - 20, iThisWinWidth, iThisWinHeight)
WindowMoveHotspot(winThisResizer, "hsBR2Resizer" .. sShorthand, iThisWinWidth - 20, iThisWinHeight - 4, iThisWinWidth - 4, iThisWinHeight)
WindowMoveHotspot(winThisResizer, "hsBResizer" .. sShorthand, 20, iThisWinHeight - 4, iThisWinWidth - 20, iThisWinHeight)
end
iMarginXStart = 0
iMarginYStart = 0
function ResizeMarginMouseDown(flags, hotspot_id)
local sMargin = string.sub(hotspot_id, -1)
local winThisResizeWin
if (sMargin == "L") then
winThisResizeWin = winScreenMarginLeft
elseif (sMargin == "T") then
winThisResizeWin = winScreenMarginTop
elseif (sMargin == "R") then
winThisResizeWin = winScreenMarginRight
elseif (sMargin == "B") then
winThisResizeWin = winScreenMarginBottom
else
return
end
iResizeXStart, iResizeYStart = WindowInfo(winThisResizeWin, 17), WindowInfo(winThisResizeWin, 18)
end
function ResizeMarginCallback(flags, hotspot_id)
local iDiffX = 0
local iDiffY = 0
local winThisResizeWin
local sMargin = string.sub(hotspot_id, -1)
if (sMargin == "L") then
winThisResizeWin = winScreenMarginLeft
elseif (sMargin == "T") then
winThisResizeWin = winScreenMarginTop
elseif (sMargin == "R") then
winThisResizeWin = winScreenMarginRight
elseif (sMargin == "B") then
winThisResizeWin = winScreenMarginBottom
else
return
end
local iResizeXEnd = WindowInfo(winThisResizeWin, 17)
local iResizeYEnd = WindowInfo(winThisResizeWin, 18)
if (sMargin == "L") then
iDiffX = iResizeXEnd - iResizeXStart
SCREENMARGINS["left"][2] = SCREENMARGINS["left"][2] + iDiffX
WindowPosition(winScreenMarginLeft, SCREENMARGINS["left"][2] - 4, 0, 0, 2)
RedoScreenMargins()
Redraw()
elseif (sMargin == "T") then
iDiffY = iResizeYEnd - iResizeYStart
SCREENMARGINS["top"][2] = SCREENMARGINS["top"][2] + iDiffY
WindowPosition(winScreenMarginTop, 0, SCREENMARGINS["top"][2] - 4, 0, 2)
RedoScreenMargins()
Redraw()
elseif (sMargin == "R") then
iDiffX = iResizeXStart - iResizeXEnd
if ((SCREENMARGINS["right"][2] + iDiffX) >= 4) then
SCREENMARGINS["right"][2] = SCREENMARGINS["right"][2] + iDiffX
WindowPosition(winScreenMarginRight, GetInfo(281) - SCREENMARGINS["right"][2], 0, 0, 2)
RedoScreenMargins()
Redraw()
end
elseif (sMargin == "B") then
iDiffY = iResizeYStart - iResizeYEnd
if ((SCREENMARGINS["bottom"][2] + iDiffY) >= 4) then
SCREENMARGINS["bottom"][2] = SCREENMARGINS["bottom"][2] + iDiffY
WindowPosition(winScreenMarginBottom, 0, GetInfo(280) - SCREENMARGINS["bottom"][2], 0, 2)
RedoScreenMargins()
Redraw()
end
end
iThemeLayoutLocked = 0
iResizeXStart, iResizeYStart = WindowInfo(winThisResizeWin, 17), WindowInfo(winThisResizeWin, 18)
end
-- Store initial mouse click in the resize window edges
iResizeXStart = 0
iResizeYStart = 0
function ResizeWindowMouseDown(flags, hotspot_id)
local winThisResizeWin
if (string.sub(hotspot_id, -3) == "Map") then
winThisResizeWin = winMinimap
elseif (string.sub(hotspot_id, -3) == "MDT") then
winThisResizeWin = winMDT
elseif (string.sub(hotspot_id, -3) == "Bar") then
winThisResizeWin = winBars
elseif (string.sub(hotspot_id, -2) == "XP") then
winThisResizeWin = winXP
elseif (string.sub(hotspot_id, -5) == "Stats") then
winThisResizeWin = winStats
elseif (string.sub(hotspot_id, -7) == "Shields") then
winThisResizeWin = winShields
elseif (string.sub(hotspot_id, -5) == "Comms") then
winThisResizeWin = winComms
elseif (string.sub(hotspot_id, -5) == "Ascii") then
winThisResizeWin = winAscii
else
return
end
iResizeXStart, iResizeYStart = WindowInfo(winThisResizeWin, 17), WindowInfo(winThisResizeWin, 18)
end
-- Handle live resize dragging of a window
function ResizeMoveCallback(flags, hotspot_id)
local iDiffX = 0
local iDiffY = 0
local winThisResizeWin
if (string.sub(hotspot_id, -3) == "Map") then
winThisResizeWin = winMinimap
elseif (string.sub(hotspot_id, -3) == "MDT") then
winThisResizeWin = winMDT
elseif (string.sub(hotspot_id, -3) == "Bar") then
winThisResizeWin = winBars
elseif (string.sub(hotspot_id, -2) == "XP") then
winThisResizeWin = winXP
elseif (string.sub(hotspot_id, -5) == "Stats") then
winThisResizeWin = winStats
elseif (string.sub(hotspot_id, -7) == "Shields") then
winThisResizeWin = winShields
elseif (string.sub(hotspot_id, -5) == "Comms") then
winThisResizeWin = winComms
elseif (string.sub(hotspot_id, -5) == "Ascii") then
winThisResizeWin = winAscii
else
return
end
-- No resizing for locked windows
if (WINDATA[winThisResizeWin]["LOCKED"] == true) then
return
end
local iResizeXEnd = WindowInfo(winThisResizeWin, 17)
local iResizeYEnd = WindowInfo(winThisResizeWin, 18)
if (string.sub(hotspot_id, 1, 5) == "hsLRe") then
iDiffX = iResizeXStart - iResizeXEnd
WindowPosition(winThisResizeWin, WindowInfo(winThisResizeWin, 1) - iDiffX, WindowInfo(winThisResizeWin, 2), 0, 2)
if (string.sub(hotspot_id, -3) == "Map") then
winInfoMinimap.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -3) == "MDT") then
winInfoMDT.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -3) == "Bar") then
winInfoBars.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -2) == "XP") then
winInfoXP.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -5) == "Stats") then
winInfoStats.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -7) == "Shields") then
winInfoShields.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -5) == "Comms") then
winInfoComms.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -5) == "Ascii") then
winInfoAscii.window_left = WindowInfo(winThisResizeWin, 10)
end
elseif (string.sub(hotspot_id, 1, 5) == "hsBL1" or string.sub(hotspot_id, 1, 5) == "hsBL2") then
iDiffX = iResizeXStart - iResizeXEnd
iDiffY = iResizeYEnd - iResizeYStart
WindowPosition(winThisResizeWin, WindowInfo(winThisResizeWin, 1) - iDiffX, WindowInfo(winThisResizeWin, 2), 0, 2)
if (string.sub(hotspot_id, -3) == "Map") then
winInfoMinimap.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -3) == "MDT") then
winInfoMDT.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -3) == "Bar") then
winInfoBars.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -2) == "XP") then
winInfoXP.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -5) == "Stats") then
winInfoStats.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -7) == "Shields") then
winInfoShields.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -5) == "Comms") then
winInfoComms.window_left = WindowInfo(winThisResizeWin, 10)
elseif (string.sub(hotspot_id, -5) == "Ascii") then
winInfoAscii.window_left = WindowInfo(winThisResizeWin, 10)
end
elseif (string.sub(hotspot_id, 1, 5) == "hsRRe") then
iDiffX = iResizeXEnd - iResizeXStart
elseif (string.sub(hotspot_id, 1, 5) == "hsBRe") then
iDiffY = iResizeYEnd - iResizeYStart
elseif (string.sub(hotspot_id, 1, 5) == "hsBR1" or string.sub(hotspot_id, 1, 5) == "hsBR2") then
iDiffX = iResizeXEnd - iResizeXStart
iDiffY = iResizeYEnd - iResizeYStart
end
iResizeXStart, iResizeYStart = WindowInfo(winThisResizeWin, 17), WindowInfo(winThisResizeWin, 18)
if (string.sub(hotspot_id, -3) == "Map") then
-- Special case for minimap window changes
ResizeRedrawWindowMinimap(WINDATA[winMinimap]["WIDTH"] + iDiffX, WINDATA[winMinimap]["HEIGHT"] + iDiffY)
elseif (string.sub(hotspot_id, -3) == "MDT") then
-- MDT window changes
ResizeRedrawWindowGeneric(winMDT, WINDATA[winMDT]["WIDTH"] + iDiffX, WINDATA[winMDT]["HEIGHT"] + iDiffY, "MDT")
-- And re-draw the MDT data
RedrawMDTWindow()
Redraw()
elseif (string.sub(hotspot_id, -3) == "Bar") then
-- Bars window changes
ResizeRedrawWindowGeneric(winBars, WINDATA[winBars]["WIDTH"] + iDiffX, WINDATA[winBars]["HEIGHT"] + iDiffY, "Bar")
-- And re-draw the MDT data
RedrawVitalsWindow()
Redraw()
elseif (string.sub(hotspot_id, -2) == "XP") then
-- XP window changes
ResizeRedrawWindowGeneric(winXP, WINDATA[winXP]["WIDTH"] + iDiffX, WINDATA[winXP]["HEIGHT"] + iDiffY, "XP")
-- And re-draw the MDT data
RedrawXPWindow(true)
Redraw()
elseif (string.sub(hotspot_id, -5) == "Stats") then
-- Stats window changes
ResizeRedrawWindowGeneric(winStats, WINDATA[winStats]["WIDTH"] + iDiffX, WINDATA[winStats]["HEIGHT"] + iDiffY, "Stats")
-- And re-draw the MDT data
RedrawStatsWindow()
Redraw()
elseif (string.sub(hotspot_id, -7) == "Shields") then
-- Shields window changes
ResizeRedrawWindowGeneric(winShields, WINDATA[winShields]["WIDTH"] + iDiffX, WINDATA[winShields]["HEIGHT"] + iDiffY, "Shields")
-- And re-draw the Shields data
RedrawShieldsWindow()
Redraw()
elseif (string.sub(hotspot_id, -5) == "Comms") then
-- Comms window changes
ResizeRedrawWindowGeneric(winComms, WINDATA[winComms]["WIDTH"] + iDiffX, WINDATA[winComms]["HEIGHT"] + iDiffY, "Comms")
bCommsNeedsButtons = true
-- And re-draw the Comms data
bCommsNeedsButtons = true
RedrawCommsWindow()
elseif (string.sub(hotspot_id, -5) == "Ascii") then
-- Ascii-Map window changes
ResizeRedrawWindowGeneric(winAscii, WINDATA[winAscii]["WIDTH"] + iDiffX, WINDATA[winAscii]["HEIGHT"] + iDiffY, "Ascii")
-- And re-draw the Ascii data
RedrawAsciiWindow()
Redraw()
end
iThemeLayoutLocked = 0
end
-- Re-draw generic windows with global drag handlers again
function ResizeRedrawWindowGeneric(winNewSize, iNewSizeX, iNewSizeY, sShortcut)
WINDATA[winNewSize]["WIDTH"] = iNewSizeX
WINDATA[winNewSize]["HEIGHT"] = iNewSizeY
WindowResize(winNewSize, WINDATA[winNewSize]["WIDTH"], WINDATA[winNewSize]["HEIGHT"], iGlobalColourBlack)
-- Change the drag-area hotspot
if (winNewSize ~= winComms) then
WindowMoveHotspot(winNewSize, "zz_mw_" .. winNewSize .. "_movewindow_hotspot", 0, 0, WINDATA[winNewSize]["WIDTH"], WINDATA[winNewSize]["HEIGHT"])
else
WindowMoveHotspot(winComms, "zz_mw_" .. winComms .. "_movewindow_hotspot", 0, iTopCommsWindow, WINDATA[winComms]["WIDTH"], WINDATA[winComms]["HEIGHT"])
WindowMoveHotspot(winComms, "hsCommsUp", WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH + 1), iTopCommsWindow, WINDATA[winComms]["WIDTH"]-1, SCROLL_BAR_WIDTH + iTopCommsWindow)
WindowMoveHotspot(winComms, "hsCommsDown", WINDATA[winComms]["WIDTH"]-(SCROLL_BAR_WIDTH + 1), WINDATA[winComms]["HEIGHT"]-(SCROLL_BAR_WIDTH), WINDATA[winComms]["WIDTH"]-1, WINDATA[winComms]["HEIGHT"]-1)
WindowMoveHotspot(winComms, "hsChatTabs", 0, 0, WINDATA[winComms]["WIDTH"], iTopCommsWindow)
end
-- And now update the window-edge areas
UpdateResizableWindow(winNewSize, sShortcut, WINDATA[winNewSize]["WIDTH"], WINDATA[winNewSize]["HEIGHT"])
end
-- Re-draw the minimap window a new size
function ResizeRedrawWindowMinimap(iNewSizeX, iNewSizeY)
WINDATA[winMinimap]["WIDTH"] = iNewSizeX
WINDATA[winMinimap]["HEIGHT"] = iNewSizeY
MINIMAP_WIDTH = WINDATA[winMinimap]["WIDTH"]
MINIMAP_HEIGHT = WINDATA[winMinimap]["HEIGHT"]-winThemeData.TITLE_HEIGHT
MINIMAP_X = 0
MINIMAP_Y = winThemeData.TITLE_HEIGHT
MINIMAP_CX = math.floor(MINIMAP_WIDTH/2)
MINIMAP_CY = math.floor(MINIMAP_HEIGHT/2)+winThemeData.TITLE_HEIGHT
WindowResize(winMinimap, WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"], iGlobalColourBlack)
-- Change the drag-area hotspot
WindowMoveHotspot(winMinimap, "zz_mw_" .. winMinimap .. "_movewindow_hotspot", 0, 0, WINDATA[winMinimap]["WIDTH"], winThemeData.TITLE_HEIGHT)
-- Change the main map-area click area
WindowMoveHotspot(winMinimap, "hsMapClick", 4, winThemeData.TITLE_HEIGHT, WINDATA[winMinimap]["WIDTH"] - 4, WINDATA[winMinimap]["HEIGHT"] - 4)
-- And now update the window-edge areas
UpdateResizableWindow(winMinimap, "Map", WINDATA[winMinimap]["WIDTH"], WINDATA[winMinimap]["HEIGHT"])
-- Re-do the window title
if (sQuowMapfiles[iCurMap] ~= nil) then
RetitleWindow(winMinimap, sQuowMapfiles[iCurMap][2])
else
RetitleWindow(winMinimap, "Graphical Minimap")
end
-- Redraw the map
RedrawMap()
end
-- Enabling the plugin
function OnPluginEnable()
-- Always enable the map window
local bAnyWindows = false
if (WINDATA[winMinimap]["SHOW"] == true) then
WindowShow(winMinimap, true)
ClearMinimapWindow()
RedrawMap()
bAnyWindows = true
end
-- Optional MDT window
if (WINDATA[winMDT]["SHOW"] == true) then
WindowShow(winMDT, true)
RedrawMDTWindow()
bAnyWindows = true
end
-- Optional vitals window
if (WINDATA[winBars]["SHOW"] == true) then
WindowShow(winBars, true)
RedrawVitalsWindow()
bAnyWindows = true
end
-- Optional XP window
if (WINDATA[winXP]["SHOW"] == true) then
WindowShow(winXP, true)
RedrawXPWindow(true)
bAnyWindows = true
end
-- Stats window
if (WINDATA[winStats]["SHOW"] == true) then
WindowShow(winStats, true)
RedrawStatsWindow()
bAnyWindows = true
end
-- Shields window
if (WINDATA[winShields]["SHOW"] == true) then
WindowShow(winShields, true)
RedrawShieldsWindow()
bAnyWindows = true
end
-- Ascii-Map window
if (WINDATA[winAscii]["SHOW"] == true) then
WindowShow(winAscii, true)
RedrawAsciiWindow()
bAnyWindows = true
end
-- Comms window
if (WINDATA[winComms]["SHOW"] == true) then
WindowShow(winComms, true)
bCommsNeedsButtons = true
RedrawCommsWindow()
bAnyWindows = true
end
if (bAnyWindows == false) then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "Quow's Cow Bar is running, but you have all windows set to hidden!")
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You can use '", sGlobalColourCyan, sGlobalColourBlack, "minimap show", sGlobalColourOrange, sGlobalColourBlack, "' or '", sGlobalColourCyan, sGlobalColourBlack, "minimap reset", sGlobalColourOrange, sGlobalColourBlack, "' to show the main window or reset all core windows.")
elseif (WINDATA[winMinimap]["SHOW"] == false) then
ColourNote(sGlobalColourOrange, sGlobalColourBlack, "You have the main minimap window hidden. Use '", sGlobalColourCyan, sGlobalColourBlack, "minimap show", sGlobalColourOrange, sGlobalColourBlack, "' to display again.")
ColourNote(sGlobalColourSilver, sGlobalColourBlack, "Note: MANY options and features of Cow Bar are controlled through the minimap window menu!")
end
Redraw()
end -- function OnPluginEnable
-- Disabling the plugin
function OnPluginDisable()
-- Always hide all windows so we don't leave a mess on the screen
WindowShow(winMinimap, false)
WindowShow(winMDT, false)
WindowShow(winBars, false)
WindowShow(winXP, false)
WindowShow(winStats, false)
WindowShow(winShields, false)
WindowShow(winComms, false)
WindowShow(winAscii, false)
end -- function OnPluginDisable
-- Closing the plugin
function OnPluginClose()
-- Called on plugin reinstalls, world close, mushclient exit
-- Record combat stats
if (iCurrentCombatStatSet ~= 0) then
sSQL = "UPDATE combat_stats SET "
for sColumn, sData in pairs(iQuowCombatStats[iCurrentCombatStatSet]) do
if (sColumn ~= "set_name") then
sSQL = sSQL .. sColumn .. "=" .. sData .. ","
else
sSQL = sSQL .. sColumn .. "='" .. EscapeSQL(sData) .. "',"
end
end
sSQL = string.sub(sSQL, 1, -2)
sSQL = sSQL .. " WHERE set_id=" .. iCurrentCombatStatSet
assert(dbUserData:execute(sSQL))
end
-- Close the database
dbMap:close()
dbUserData:close()
-- If this plugin is currently enabled, call the disable cleanup function
if GetPluginInfo (GetPluginID(), 17) then
OnPluginDisable()
end -- if enabled
-- Reset text rectangle
TextRectangle(iOldTextRectangleData[1], iOldTextRectangleData[2], iOldTextRectangleData[3], iOldTextRectangleData[4], 1, 0, 0, 0, 0)
end -- function OnPluginClose
function OnPluginSaveState()
-- Do not do database stuff here, as OnPluginClose is called FIRST!
--Note("Plugin save state function, saving stuff....")
--assert(dbUserData:execute(sSQL))
SetVariable ("enabled", tostring(GetPluginInfo(GetPluginID(), 17)))
-- Save window locations
movewindow.save_state(winMinimap)
movewindow.save_state(winMDT)
movewindow.save_state(winBars)
movewindow.save_state(winXP)
movewindow.save_state(winStats)
movewindow.save_state(winShields)
movewindow.save_state(winComms)
movewindow.save_state(winAscii)
-- User save-state variables
SetVariable("sUserFont", tostring(sUserFont))
SetVariable("iFontSize", tostring(iFontSize))
SetVariable("iCurrentChannelChoice", tostring(iCurrentChannelChoice))
SetVariable("sQuowMapPath", tostring(sQuowMapPath))
SetVariable("bOptimisedCombatTriggers", tostring(bOptimisedCombatTriggers))
SetVariable("iThemeLayoutLocked", tostring(iThemeLayoutLocked))
SetVariable("WINDATA", json.encode(WINDATA))
SetVariable("SCREENMARGINS", json.encode(SCREENMARGINS))
SetVariable("CUSTOMCOWS", json.encode(CUSTOMCOWS))
SetVariable("MODULES", json.encode(MODULES))
SetVariable("bLockMargins", tostring(bLockMargins))
SetVariable("iCurMap", tostring(iCurMap))
SetVariable("iMyX", tostring(iMyX))
SetVariable("iMyY", tostring(iMyY))
SetVariable("bHideOnTerrain", tostring(bHideOnTerrain))
SetVariable("bAutoShowHideAscii", tostring(bAutoShowHideAscii))
SetVariable("bAsciiMapOmitted", tostring(bAsciiMapOmitted))
SetVariable("bDrawOrbs", tostring(bDrawOrbs))
SetVariable("bPredictiveMoves", tostring(bPredictiveMoves))
SetVariable("bDrawSkeletonMode", tostring(bDrawSkeletonMode))
SetVariable("bHandlerSM", tostring(bHandlerSM))
SetVariable("bHandlerLib", tostring(bHandlerLib))
SetVariable("bDebugMode", tostring(bDebugMode))
SetVariable("bShowGhost", tostring(bShowGhost))
SetVariable("iOldMap", tostring(iOldMap))
SetVariable("iOldMX", tostring(iOldMX))
SetVariable("iOldMY", tostring(iOldMY))
SetVariable("bRequestRoomMap", tostring(bRequestRoomMap))
SetVariable("bRequestWrittenMap", tostring(bRequestWrittenMap))
SetVariable("bRequestCharVitals", tostring(bRequestCharVitals))
SetVariable("sCurrentRoomID", sCurrentRoomID)
SetVariable("sClickedRoomID", sClickedRoomID)
SetVariable("sLastDir", sLastDir)
SetVariable("iMinimapBrightness", tostring(iMinimapBrightness))
SetVariable("bVitalStacking", tostring(bVitalStacking))
SetVariable("bShowDiscDate", tostring(bShowDiscDate))
SetVariable("sMyPlayerName", tostring(sMyPlayerName))
SetVariable("bShowDiscDate", tostring(bShowDiscDate))
SetVariable("bShowCommsTabs", tostring(bShowCommsTabs))
SetVariable("bPlayGPNotification", tostring(bPlayGPNotification))
SetVariable("bShowHPNotifications", tostring(bShowHPNotifications))
SetVariable("bShowXPNotifications", tostring(bShowXPNotifications))
SetVariable("sGPNotificationFile", tostring(sGPNotificationFile))
SetVariable("objChatFilters", json.encode(objChatFilters))
SetVariable("objChatTabs", json.encode(objChatTabs))
end -- function OnPluginSaveState
-- Delete the minimap window and wipe it clean
function ClearMinimapWindow()
WindowRectOp(winMinimap, miniwin.rect_fill, MINIMAP_X, MINIMAP_Y, MINIMAP_WIDTH, WINDATA[winMinimap]["HEIGHT"], iGlobalColourBlack)
if (sQuowMapfiles[iCurMap] ~= nil) then
RetitleWindow(winMinimap, sQuowMapfiles[iCurMap][2])
else
RetitleWindow(winMinimap, "Graphical Minimap")
end
end
-- Redraw the title bar and then write some text on it
function RetitleWindow(winTitlethis, sTitleBar)
-- Title bar
DrawThemed3DRect(winTitlethis, 0, 0, WINDATA[winTitlethis]["WIDTH"], winThemeData.TITLE_HEIGHT)
-- Title text
local iFWidth = WindowTextWidth (winTitlethis, "titlefont"..winMinimap, sTitleBar)
local iIndent = (WINDATA[winTitlethis]["WIDTH"]/2) - (iFWidth/2)
WindowText(winTitlethis, "titlefont"..winMinimap, sTitleBar, iIndent, (winThemeData.TITLE_HEIGHT-iGlobalLineHeight)/2, WINDATA[winTitlethis]["WIDTH"], winThemeData.TITLE_HEIGHT, winThemeData.DETAIL, false)
-- Let mushclient know we need a non-urgent redraw of the windows because of this change
Redraw()
end
-- Convert the long-descriptions table into triggers
for iKey, sLongLocation in ipairs(sQuowLocationsByLong) do
local sShort = tostring(sLongLocation[1])
local sLong = tostring(sLongLocation[2])
local iThisFlags = 1+8+32
AddTriggerEx(tostring(sShort), tostring(sLong), "", iThisFlags, -1, 0, "", "MapLongHandler", 12, 5)
SetTriggerOption(sShort, "group", "module_minimap")
end
-- **********************************************************
-- ***** Combat Line Regex Builder/Manipulator/CowTools *****
-- **********************************************************
iCustomCombatLinesNormal = 0
iCustomCombatLinesFailNormal = 0
iCustomCombatLinesSpecial = 0
iTotalCombatTriggers = 0
function CombatRegexBuilder()
-- These are the primary texts that will be chopped up, thrown together, and turned into large regexes
local sCombatTexts = {
-- Normal attacks
-- Blunt hits 1
{"^<attacker> swings at <victim> with <weapon>\.$", false, 1},
{"^<attacker> taps <victim> in the <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> hits <victim> in the <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> bruises <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> hits <victim> hard in the <bodypart> with <weapon>\.$", false, 5},
{"^<attacker> smashes <victim> in the <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> crushes <victim><vic_pl> <bodypart> with <weapon>\.$", false, 7},
{"^<attacker> mashes <victim><vic_pl> <bodypart> with <weapon>\.$", false, 8},
-- Blunt hits 2
{"^<attacker> strikes at <victim> with <weapon>\.$", false, 1},
{"^<attacker> taps <victim> in the <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> knocks <victim><vic_pl> <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> bruises <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> bashes <victim> in the <bodypart> with <weapon>\.$", false, 5},
{"^<attacker> beats <victim> in the <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> smashes <weapon> into <victim><vic_pl> <bodypart>\.$", false, 7},
{"^<attacker> smashes <victim> in the <bodypart> with <weapon>\.$", false, 8},
-- Blunt hits 3
{"^<attacker> strikes at <victim> with <weapon>\.$", false, 1},
{"^<attacker> taps <victim><vic_pl> <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> knocks <victim><vic_pl> <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> strikes <victim> lightly in the <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> strikes <victim> in the <bodypart> with <weapon>\.$", false, 5},
{"^<attacker> strikes <victim> hard in the <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> batters <victim><vic_pl> <bodypart> with <weapon>\.$", false, 7},
{"^<attacker> bludgeons <victim><vic_pl> <bodypart> with <weapon>\.$", false, 8},
-- Rolling pins
{"^<attacker> swipes at <victim> with <weapon>\.$", false, 1},
{"^<attacker> belts <victim> on the <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> wallops <victim> neatly on the <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> smashes <victim> on the <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> batters <victim> on the <bodypart> with <weapon>\.$", false, 5},
{"^<attacker> smashes <victim> heavily on the <bodypart> with <weapon>\.$", false, 6},
-- Frying pan
{"^<attacker> enthusiastically swings at <victim> with <weapon>\.$", false, 1},
{"^<attacker> swipes <victim> lightly on the <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> dings <victim> smartly on the <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> belts <victim> hard on the <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> thumps <victim> heavily on the <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> winds up and mashes <victim> heavily on the <bodypart> with <weapon>\.$", false, 5},
-- Ornate Warhammer
{"^<attacker> attempts to bash <victim> with <weapon>\.$", false, 1},
{"^<attacker> attempts to smash <victim> with <weapon>\.$", false, 1},
{"^<attacker> attempts to bludgeon <victim> with <weapon>\.$", false, 1},
{"^<attacker> bashes <weapon> into <victim><vic_pl> <bodypart>\.$", false, 2},
{"^<attacker> bashes <victim><vic_pl> <bodypart> with <weapon>, knocking <v_him> back a step\.$", false, 2},
{"^<attacker> smashes <weapon> into <victim><vic_pl> <bodypart> with an audible crack\.$", false, 3},
{"^<attacker> smashes <weapon> into <victim>, eliciting a loud crack from <v_his> <bodypart>\.$", false, 4},
{"^<attacker> bludgeons <victim> with <weapon>, causing blood to spray from <v_his> <bodypart>\.$", false, 5},
{"^<attacker> bludgeons <victim> with <weapon>, leaving a bloody weal on <v_his> <bodypart>\.$", false, 5},
{"^<attacker> bludgeons <victim> with <weapon>, causing a sudden spurt of blood from <v_his> <bodypart>\.$", false, 6},
{"^<attacker> bludgeons <victim> with <weapon>, causing blood to splatter all over the area\.$", false, 6},
{"^<attacker> bludgeons <victim> with <weapon>, causing blood to flood out of her body\.$", false, 7},
{"^<attacker> bludgeons <victim> with <weapon>, making blood trickle out of <v_his> <bodypart>\.$", false, 8},
{"^<attacker> smashes <weapon> into <victim><vic_pl> <bodypart>, producing a series of unpleasant cracking noises\.$", false, 7},
{"^<attacker> bashes <victim><vic_pl> <bodypart> with <weapon>; you can hear the sound of breaking bones\.$", false, 8},
{"^<attacker> bashes <victim> with <weapon>; you can hear the sound of splintering bones\.$", false, 8},
{"^<attacker> smashes <weapon> into <victim><vic_pl> <bodypart> so hard that you can hear the sound of bones breaking\.$", false, 8},
-- Ukuleles
{"^<attacker> attempts to hit <victim> with <weapon>\.$", false, 1},
{"^<attacker> hits <victim><vic_pl> <bodypart> with <weapon> delivering a terrible sounding (?>C|A|F) (?>flat|sharp)\.$", false, 2},
{"^<attacker> hits <victim><vic_pl> <bodypart> with <weapon> producing a cheerful ukulele-solo\.$", false, 4},
{"^<attacker> hits <victim><vic_pl> <bodypart> with <weapon> producing an abstract A\.$", false, 5},
{"^<attacker> hits <victim><vic_pl> <bodypart> hard with <weapon> producing a nice A\.$", false, 5},
{"^<attacker> smacks <weapon> into <victim><vic_pl> <bodypart> causing a vibrating and fascinating sound\.$", false, 5},
{"^<attacker> mashes <victim><vic_pl> <bodypart> with <weapon>, generating a glass-shattering symphony in (?>E flat|C sharp) of Woe\.$", false, 6},
{"^<attacker> slams <weapon> repeatedly in <victim><vic_pl> <bodypart> performing an impressive aria of glass-shattering tones\.$", false, 8},
-- Whips
{"^<attacker> flicks at <victim> with <weapon>\.$", false, 1},
{"^<attacker> flails at <victim> with <weapon>\.$", false, 1},
{"^<attacker> flicks <victim><vic_pl> <bodypart> gently with <weapon>\.$", false, 2},
{"^<attacker> lashes <victim><vic_pl> <bodypart> painfully with <weapon>\.$", false, 3},
{"^<attacker> raises a welt on <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> hit <victim><vic_pl> <bodypart> with <weapon>, causing a loud cracking noise\.$", false, 5},
{"^<attacker> flicks <weapon> expertly, cutting <victim><vic_pl> <bodypart> deeply\.$", false, 6},
{"^<attacker> causes a deep gash, striking <victim><vic_pl> <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> catches a tender spot on <victim><vic_pl> <bodypart> with <weapon>, leaving a flaming line of agony\.$", false, 7},
{"^<attacker> flay <victim><vic_pl> <bodypart> to tatters with <weapon>\.$", false, 8},
-- Holy Water Whips
{"^<attacker> flicks at <victim> with <weapon>, sprinkling water everywhere\.$", false, 1},
{"^<attacker> raises a welt on <victim><vic_pl> <bodypart> with <weapon>, infusing the welt with water\.$", false, 4},
{"^<attacker> flay <victim><vic_pl> <bodypart> to tatters with <weapon>, spraying water everywhere\.$", false, 8},
-- Hooter of death
{"^<attacker> bonks <victim> with <weapon>\.$", false, 1},
{"^<attacker> honks at <victim> with <weapon>\.$", false, 1},
{"^<attacker> smacks <weapon> at <victim> causing their head to vibrate\.$", false, 2},
{"^<attacker> honks <weapon> at <victim> causing their head to vibrate\.$", false, 3},
{"^<attacker> honks at <victim> with <weapon>, making a deafening HONKKK\.$", false, 4},
{"^<attacker> mashes <victim> with <weapon>, making it emit a loud honk\.$", false, 5},
-- Dictionary of cussing
--Kly Bell pokes fun of your relationships with goats. You blush furiously but you deftly dodge out of the way.
--Kly Bell exclaims "Er... Bloody hell???" You barely notice but you dodge out of the way.
-- Metal dragon
{"^<attacker> brushes <victim> with a swing of <a_his> tail\.$", true, 1},
-- Conkers
{"^<attacker> cracks <weapon> across <victim><vic_pl> knuckles\.$", false, 2},
{"^<attacker> whacks <weapon> between <victim><vic_pl> eyes\.$", false, 3},
{"^<attacker> smacks <victim> upside the head with <weapon>\.$", false, 4},
-- Antlers
{"^<attacker> touches <victim> with <weapon>\.$", false, 1},
{"^<attacker> prods at <victim> with <weapon>\.$", false, 1},
{"^<attacker> jabs at <victim> with <weapon>\.$", false, 1},
{"^<attacker> thrusts at <victim> with a pointy bit of <weapon>\.$", false, 2},
{"^<attacker> stabs <victim> in the <bodypart> with a pointy bit of <weapon>\.$", false, 3},
-- Escrow werewolves
--{"^<attacker> tears at <victim><vic_pl> <bodypart> with <weapon>\.$", false, 1},
--{"^<attacker> bites at <victim><vic_pl> <bodypart> with <weapon>\.$", false, 1},
-- Moose
-- Lit Torch
{"^<attacker> attempts to burn <victim>\.$", false, 1},
{"^<attacker> smokes <victim>\.$", false, 1},
{"^<attacker> singes <victim>\.$", false, 2},
{"^<attacker> crisps <victim>\.$", false, 3},
{"^<attacker> scorches <victim>\.$", false, 3},
{"^<attacker> toasts <victim>\.$", false, 4},
{"^<attacker> chars <victim>\.$", false, 4},
{"^<attacker> burns <victim>\.$", false, 5},
{"^<attacker> fries <victim>\.$", false, 5},
{"^<attacker> roasts <victim>\.$", false, 6},
{"^<attacker> melts (?!in )<victim>\.$", false, 6},
{"^<attacker> incinerates <victim>\.$", false, 7},
{"^<attacker> cremates <victim>\.$", false, 7},
{"^<attacker> vapourises <victim>\.$", false, 8},
-- Holy weapon
{"^<attacker> attempts to burn <victim> with <weapon>\.$", false, 1},
{"^<attacker> touches <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 2},
{"^<attacker> singes <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 3},
{"^<attacker> gently scorches <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 4},
{"^<attacker> scorches <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 4},
{"^<attacker> burns <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 5},
{"^<attacker> gives <victim><vic_pl> <bodypart> a painful burn with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 5},
{"^<attacker> crisps <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 6},
{"^<attacker> chars <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 6},
{"^<attacker> sears <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 7},
{"^<attacker> fries <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 7},
{"^<attacker> roasts <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 8},
{"^<attacker> incinerates <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 8},
{"^<attacker> cremates <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 9},
{"^<attacker> vaporises <victim><vic_pl> <bodypart> with the (?>faint|pale|steady|flickering|bright|intense|incandescent) (?>lilac|violet|lavender|jade|chartreuse|emerald|saffron|amber|silver|ash grey|azure|cerulean|sapphire|tangerine|orange|crimson|ruby|vermilion) holy (?>light|flames) surrounding <weapon>\.$", false, 9},
-- Slash hits 1
{"^<attacker> slashes at <victim> with <weapon>\.$", false, 1},
{"^<attacker> snicks <victim><vic_pl> <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> scratches <victim><vic_pl> <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> nicks <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> cuts <victim><vic_pl> <bodypart> with <weapon>\.$", false, 5},
{"^<attacker> slices <victim><vic_pl> <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> hacks <victim><vic_pl> <bodypart> with <weapon>\.$", false, 7},
{"^<attacker> chops up <victim><vic_pl> <bodypart> with <weapon>\.$", false, 8},
-- Slash hits 2
{"^<attacker> slices at <victim> with <weapon>\.$", false, 1},
{"^<attacker> just manages to slice <victim><vic_pl> <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> slices <weapon> across <victim><vic_pl> <bodypart>\.$", false, 3},
{"^<attacker> shreds <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> slices <weapon> into <victim><vic_pl> <bodypart>\.$", false, 5},
{"^<attacker> takes a sliver off <victim><vic_pl> <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> slices <weapon> deeply into <victim><vic_pl> <bodypart>\.$", false, 7},
{"^<attacker> neatly fillets <victim><vic_pl> <bodypart> with <weapon>\.$", false, 8},
-- Headless rider
{"^<attacker> slices at <victim> with <weapon> leaving a trail of sparks in the air\.$", false, 1},
-- Missing = 2-5
{"^<attacker> takes a sliver off <victim><vic_pl> <bodypart> with <weapon>, scorching the flesh underneath\.$", false, 6},
{"^<attacker> slices <weapon> deeply into <victim><vic_pl> <bodypart> leaving a bloody and charred mess\.$", false, 7},
{"^<attacker> neatly fillets <victim><vic_pl> <bodypart> with <weapon>, the sheer heat from the blade cauterising the wound instantly\.$", false, 8},
-- Axe hits 1
{"^<attacker> swings <weapon> at <victim>\.$", false, 1},
{"^<attacker> attempts to chop <victim><vic_pl> <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> chops at <victim><vic_pl> <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> chops <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> chops <weapon> into <victim><vic_pl> <bodypart>\.$", false, 5},
{"^<attacker> hacks into <victim><vic_pl> <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> chops <weapon> deeply into <victim><vic_pl> <bodypart>\.$", false, 7},
{"^<attacker> chops <victim><vic_pl> <bodypart> into pieces with <weapon>\.$", false, 8},
-- Pierce hits 1
{"^<attacker> thrusts at <victim> with <weapon>\.$", false, 1},
{"^<attacker> barely hits <victim> in the <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> jabs <weapon> into <victim><vic_pl> <bodypart>\.$", false, 3},
{"^<attacker> pierces <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> pricks <victim><vic_pl> <bodypart> with <weapon>\.$", false, 5},
{"^<attacker> impales <victim><vic_pl> <bodypart> on <weapon>\.$", false, 6},
{"^<attacker> skewers <victim><vic_pl> <bodypart> with <weapon>\.$", false, 7},
{"^<attacker> runs <victim> through the <bodypart> with <weapon>\.$", false, 8},
{"^<attacker> makes a kebab of <victim><vic_pl> <bodypart> with <weapon>\.$", false, 9},
-- Pierce hits 2
{"^<attacker> swings at <victim> with <weapon>\.$", false, 1},
{"^<attacker> barely hits <victim> in the <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> jabs <weapon> into <victim><vic_pl> <bodypart>\.$", false, 3},
{"^<attacker> spikes <victim><vic_pl> <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> impales <victim><vic_pl> <bodypart> on <weapon>\.$", false, 5},
{"^<attacker> ventilates <victim><vic_pl> <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> exsanguinates <victim><vic_pl> <bodypart> with <weapon>\.$", false, 7},
{"^<attacker> perforates <victim><vic_pl> <bodypart> with <weapon>\.$", false, 8},
{"^<attacker> makes a mess of <victim><vic_pl> <bodypart> with <weapon>\.$", false, 9},
-- Pierce hits 3
{"^<attacker> thrusts at <victim> with <weapon>\.$", false, 1},
{"^<attacker> barely stabs <victim> in the <bodypart> with <weapon>\.$", false, 2},
{"^<attacker> stabs <victim> in the <bodypart> with <weapon>\.$", false, 3},
{"^<attacker> messily stabs <victim> in the <bodypart> with <weapon>\.$", false, 4},
{"^<attacker> stabs <victim> deeply in the <bodypart> with <weapon>\.$", false, 5},
{"^<attacker> perforates <victim><vic_pl> <bodypart> with <weapon>\.$", false, 6},
{"^<attacker> pierces <victim><vic_pl> <bodypart> with <weapon>\.$", false, 7},
{"^<attacker> stabs <weapon> right through <victim><vic_pl> <bodypart>\.$", false, 8},
-- Unarmed blunt damage?
{"^<attacker> swings at <victim>\.$", false, 1},
{"^<attacker> taps <victim> in the <bodypart>\.$", false, 2},
{"^<attacker> hits <victim> in the <bodypart>\.$", false, 3},
{"^<attacker> bruises <victim><vic_pl> <bodypart>\.$", false, 4},
{"^<attacker> hits <victim> hard in the <bodypart>\.$", false, 5},
{"^<attacker> smashes <victim> in the <bodypart>\.$", false, 6},
{"^<attacker> crushes <victim><vic_pl> <bodypart>\.$", false, 7},
{"^<attacker> mashes <victim><vic_pl> <bodypart>\.$", false, 8},
-- Punching unarmed
{"^<attacker> punches at <victim>\.$", false, 1},
{"^<attacker> pokes <victim> in the <bodypart>\.$", false, 2},
{"^<attacker> tickles <victim> in the <bodypart>\.$", false, 3},
{"^<attacker> jabs <victim> in the <bodypart>\.$", false, 4},
{"^<attacker> hits <victim> in the <bodypart> with an uppercut\.$", false, 5},
{"^<attacker> hits <victim> in the <bodypart> with a cross\.$", false, 6},
{"^<attacker> hits <victim> in the <bodypart> with a vicious hook\.$", false, 7},
{"^<attacker> beats <victim><vic_pl> <bodypart> to a pulp\.$", false, 8},
-- Kicking unarmed
{"^<attacker> kicks at <victim>\.$", false, 1},
{"^<attacker> kicks out at <victim>\.$", false, 1},
{"^<attacker> pokes (?!(?>his|her|its) tongue out|at a )<victim>\.$", false, 2},
{"^<attacker> tickles <victim> in the <bodypart> with <a_his> toes\.$", false, 3},
{"^<attacker> pokes <victim> with <a_his> foot\.$", false, 2},
{"^<attacker> kicks <victim> in the <bodypart>\.$", false, 4},
{"^<attacker> viciously boots <victim> in the <bodypart>\.$", false, 5},
{"^<attacker> kicks <victim> in the <bodypart>\.$", false, 6},
{"^<attacker> viciously kicks <victim> in the <bodypart>\.$", false, 7},
{"^<attacker> kicks <victim><vic_pl> <bodypart> into a bloody mess\.$", false, 8},
-- Newer special flying knee unarmed stuff
{"^<attacker> lifts <a_his> knee at <victim>\.$", false, 1},
{"^<attacker> deals <victim> a glancing blow to the <bodypart> with <a_his> knee\.$", false, 2},
{"^<attacker> knees <victim> painfully in the <bodypart>\.$", false, 3},
{"^<attacker> violently knees <victim> in the <bodypart>\.$", false, 4},
{"^<attacker> crunches <a_his> knee into <victim><vic_pl> <bodypart>\.$", false, 5},
{"^<attacker> pounds <victim> in the <bodypart> with a straight knee strike\.$", false, 6},
{"^<attacker> leaps at <victim> smashing .+? <bodypart> with a flying knee attack\.$", false, 7},
-- Throwing weapons
{"^<attacker> pierces <victim><vic_pl> <bodypart>\.$", false, 2},
-- Creeping Doom
{"^<attacker> bugs attempt to converge on <victim>\.$", true, 1},
{"^<attacker> cloud attempts to smother <victim>\.$", true, 1},
{"^<attacker> cloud moves hungrily toward <victim><vic_pl> tasty flesh\.$", true, 1},
{"^<attacker> bugs converges on <victim>\.$", true, 2},
{"^<attacker> bugs pass over <victim>, their bites raising many welts\.$", true, 3},
{"^<attacker> bugs cover <victim>, biting and raising angry red welts\.$", true, 4},
{"^<attacker> swirl around <victim>, biting and stinging <v_him> painfully\.$", true, 5},
{"^<attacker> whirl around <victim>, their bites leaving small marks\.$", true, 6},
{"^<attacker> of insects descend upon <victim>, smothering with their bodies\.$", true, 7},
{"^<attacker> of insects traps <victim> snacking on the <wild><vic_pl> flesh\.$", true, 7},
{"^<attacker> cloud smothers <victim>\.$", true, 2},
{"^<attacker> cloud lands, biting <victim>\.$", true, 3},
{"^<attacker> cloud fills <victim><vic_pl> <bodypart>\.$", true, 3},
{"^<attacker> cloud nibbles, gnawing at <victim><vic_pl> <bodypart>\.$", true, 4},
{"^<attacker> cloud nibbles, biting <victim><vic_pl> <bodypart>\.$", true, 4},
{"^<attacker> cloud twirls around <victim>, biting again and again\.$", true, 5},
{"^<attacker> cloud spins around <victim>, buzzing as the insects bite\.$", true, 6},
{"^<attacker> cloud nibbles, chewing nastily at <victim><vic_pl> <bodypart>\.$", true, 7},
{"^<attacker> cloud lands, biting <victim><vic_pl> <bodypart> again and again\.$", true, 8},
{"^<attacker> cloud covers <victim><vic_pl> <bodypart> with humming, buzzing bodies\.$", true, 9},
{"^<attacker> cloud lands, biting <victim> and leaving bloody wounds\.$", true, 9},
{"^<attacker> cloud smothers <victim>, humming bodies making it hard to breathe\.$", true, 9},
{"^<attacker> cloud bites <victim> all over, drawing blood again and again\.$", true, 9},
-- Basilisk
{"^<attacker> flakes some of <victim><vic_pl> <bodypart> off with its slime\.$", true, 1},
-- Special "fighter" NPC moves
{"^<attacker> tries to headbutt <victim>\.$", true, 1},
{"^<attacker> tries to poke <victim> in the eye\.$", true, 1},
{"^<attacker> extends a finger and pokes <victim> in the eye with a SPLOINK\.$", true, 1},
{"^<attacker> grabs <victim> roughly and headbutts <v_him> with a sharp CRACK\.$", true, 1},
-- Wrestling
{"^<attacker> grabs for <victim>\.$", false, 1},
{"^<attacker> grapples with <victim>\.$", false, 2},
{"^<attacker> catches <victim> in an arm lock\.$", false, 3},
{"^<attacker> grabs <victim> around the neck\.$", false, 4},
{"^<attacker> pokes <victim> in the face\.$", false, 5},
{"^<attacker> throws <victim> to the ground\.$", false, 6},
{"^<attacker> flings <victim> over <a_his> shoulder\.$", false, 7},
{"^<attacker> punches <victim> in the stomach\.$", false, 8},
{"^<attacker> twists <victim><vic_pl> arm painfully\.$", false, 9},
{"^<attacker> thumps <victim><vic_pl> head hard\.$", false, 10},
{"^<attacker> kicks <victim> in the back\.$", false, 11},
{"^<attacker> jumps up and down on <victim>\.$", false, 12},
{"^<attacker> slams <victim><vic_pl> head against the ground\.$", false, 13},
-- Scorpion stingers (scorpions)
{"^<attacker> stings <victim><vic_pl> <bodypart>\.$", true, 1},
-- Priesty Whirlwinds
{"^<attacker> attempts to whip <victim> with some debris\.$", true, 1},
{"^<attacker> attempts to caress <victim> with some dirty air\.$", true, 1},
{"^<attacker> attempts to choke <victim> in its dust\.$", true, 1},
{"^<attacker> nudges <victim> with some debris\.$", true, 2},
{"^<attacker> blows on <victim> causing <v_him> to stumble\.$", true, 2},
{"^<attacker> swirls around <victim> making <victim><vic_pl> <bodypart> hurt\.$", true, 2},
{"^<attacker><att_pl> swirling winds spin <victim> in circles\.$", true, 3},
{"^<attacker> swirls some dirt into <victim><vic_pl> <bodypart>\.$", true, 4},
{"^<attacker> whips <victim><vic_pl> <bodypart> with some debris\.$", true, 4},
{"^<attacker> chokes <victim> with dust\.$", true, 4},
{"^<attacker> debris whips around <victim>, pummelling <v_him>\.$", true, 4},
{"^<attacker><att_pl> huge gusts knocks <victim> to the ground\.$", true, 4},
{"^<attacker> shoves a large chunk of debris down <victim><vic_pl> throat\.$", true, 4},
{"^<attacker> whips up a really nice piece of debris and slams <victim> with it\.$", true, 5},
{"^<attacker> pummels <victim> with strong winds\.$", true, 5},
{"^<attacker> summons an extremely huge wind\. The wind pulverises <victim>\.$", true, 5},
-- Snakey coily animals (anaconda)
{"^<attacker> attempts to wrap <a_himself> around <victim><vic_pl> <bodypart>\.$", true, 1},
{"^<attacker> wraps <a_himself> around <victim><vic_pl> <bodypart> and squeezes\.$", true, 2},
-- Evil cabbage frongs
{"^<attacker> swishes at <victim><vic_pl> <bodypart> with a frond\.$", true, 1},
{"^<attacker> slashes <victim><vic_pl> <bodypart> with <a_his> fronds\.$", true, 2},
{"^<attacker> climbs onto <victim> and cuts <v_his> <bodypart> with a sharp frond\.$", true, 3},
{"^<attacker> lacerates <victim><vic_pl> <bodypart> with a frond\.$", true, 4},
-- Hind-leg hoofies (giraffes)
{"^<attacker> lashes out at <victim> with <a_his> hind legs\.$", true, 1},
{"^<attacker> lashes out with <a_his> hind legs, shattering <victim><vic_pl> <bodypart>\.$", true, 2},
-- Tusked animals (warthogs)
{"^<attacker> scratches at <victim><vic_pl> <bodypart> with one tusk\.$", true, 1},
{"^<attacker> furrows <victim><vic_pl> <bodypart> with one slavering tusk\.$", true, 2},
{"^<attacker> slashes at <victim><vic_pl> <bodypart> with <a_his> dripping tusks\.$", true, 3},
{"^<attacker> gouges <victim><vic_pl> <bodypart> with <a_his> slavering tusks\.$", true, 4},
{"^<attacker> tears <victim><vic_pl> <bodypart> open with <a_his> filthy tusks\.$", true, 5},
-- Hippo
{"^<attacker> attempts to grab <victim> in <a_his> jaws\.$", true, 1},
{"^<attacker> attempts to charge into <victim>\.$", true, 1},
-- Bull elephant charging
{"^<attacker> charges at <victim>\.$", true, 1},
{"^<attacker> stands on <a_his> hind legs and attempts to crash down on <victim>\.$", true, 1},
{"^<attacker> charges <victim> and strikes <v_him>\.$", true, 2},
{"^<attacker> swings <a_his> trunk at <victim>, hitting <v_his> <bodypart> hard\.$", true, 3},
--Tail whipping
{"^<attacker> swings <a_his> tail at <victim>\.$", true, 1},
{"^<attacker> taps <victim> in the <bodypart> with <a_his> tail\.$", true, 2},
{"^<attacker> slaps <victim> in the <bodypart> with <a_his> tail\.$", true, 2},
{"^<attacker> bruises <victim><vic_pl> <bodypart> with <a_his> tail\.$", true, 2},
{"^<attacker> hits <victim> hard in the <bodypart> with <a_his> tail\.$", true, 2},
{"^<attacker> bashes <victim> in the <bodypart> with <a_his> tail\.$", true, 2},
{"^<attacker> smashes <a_his> tail into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> sends <victim> reeling with a powerful blow to the <bodypart> with <a_his> tail\.$", true, 2},
-- T-Rex Attacks
{"^<attacker> nips at <victim> with teeth the length of a child's forearm\.$", true, 1},
{"^<attacker> rakes at <victim> with one big foot\.$", true, 1},
{"^<attacker> slashes <victim><vic_pl> <bodypart> to shreds with one powerful clawed foot\.$", true, 3},
{"^<attacker> grabs <victim><vic_pl> <bodypart> with <a_his> enormous jaws and shakes vigorously\.$", true, 4},
{"^<attacker> lowers <a_his> massive head and delicately bites <victim> in half\.$", true, 5},
-- More animals with a hoofie, like a... MOO COW
{"^<attacker> kicks out at <victim>\.$", true, 1},
{"^<attacker> taps <victim> in the <bodypart> with <a_his> hoof\.$", true, 2},
{"^<attacker> kicks <victim> in the <bodypart> with <a_his> hoof\.$", true, 2},
{"^<attacker> bruises <victim><vic_pl> <bodypart> with <a_his> hoof\.$", true, 2},
{"^<attacker> hits <victim> hard in the <bodypart> with <a_his> hoof\.$", true, 2},
{"^<attacker> smashes <victim> in the <bodypart> with <a_his> hoof\.$", true, 2},
{"^<attacker> crushes <a_his> hoof into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> mashes <victim><vic_pl> <bodypart> with <a_his> hoof\.$", true, 2},
-- Horny animals
{"^<attacker> attempts to gore <victim> with <a_his> horns\.$", true, 1},
{"^<attacker> prods <victim> in the <bodypart> with <a_his> horns\.$", true, 2},
{"^<attacker> pokes <victim> in the <bodypart> with <a_his> horns\.$", true, 2},
{"^<attacker> butts <victim> in the <bodypart> with <a_his> horns\.$", true, 2},
{"^<attacker> pierces <victim> deeply in the <bodypart> with <a_his> horns\.$", true, 2},
{"^<attacker> rams <victim> in the <bodypart> with <a_his> horns\.$", true, 2},
{"^<attacker> gores <victim><vic_pl> <bodypart> with <a_his> horns\.$", true, 2},
{"^<attacker> impales <victim><vic_pl> <bodypart> on <a_his> horns\.$", true, 2},
-- Naughty tusk animals
{"^<attacker> attempts to gore <victim> with <a_his> tusks\.$", true, 1},
{"^<attacker> prods <victim><vic_pl> <bodypart> with <a_his> tusks\.$", true, 2},
{"^<attacker> pokes <victim> in the <bodypart> with <a_his> tusks\.$", true, 2},
{"^<attacker> jabs <a_his> tusks into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> pierces <victim><vic_pl> <bodypart> with <a_his> tusks\.$", true, 2},
{"^<attacker> stabs <a_his> tusks deeply into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> gores <victim><vic_pl> <bodypart> with <a_his> tusks\.$", true, 2},
{"^<attacker> impales <victim><vic_pl> <bodypart> on <a_his> tusks\.$", true, 2},
-- Lion paws
--You claw the city guard's stomach.
--You rake at Joe Corrola with your claws but he just dodges out of the way.
--You claw the muscular soldier's right arm but her large metal shield absorbs some of the blow.
-- Clawed animals
{"^<attacker> rakes at <victim> with <a_his> claws\.$", false, 1},
{"^<attacker> snicks <victim><vic_pl> <bodypart> with <a_his> claws\.$", false, 2},
{"^<attacker> scratches <victim><vic_pl> <bodypart> with <a_his> claws\.$", false, 2},
{"^<attacker> nicks <victim><vic_pl> <bodypart> with <a_his> claws\.$", false, 2},
{"^<attacker> claws <victim><vic_pl> <bodypart>\.$", false, 2},
{"^<attacker> slices <victim><vic_pl> <bodypart> up with <a_his> claws\.$", false, 2},
{"^<attacker> hacks <victim><vic_pl> <bodypart> up with <a_his> claws\.$", false, 2},
{"^<attacker> cuts <victim><vic_pl> <bodypart> into small pieces with <a_his> claws\.$", false, 2},
-- Bitey animals
{"^<attacker> bites at <victim>\.$", true, 1},
{"^<attacker> chews on <victim><vic_pl> (?!cud|cat|keyboard|code|nose|frog|toe|ankles|finger|bones)<bodypart>\.$", true, 2},
{"^<attacker> munches on <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> gashes <victim><vic_pl> <bodypart> with <a_his> teeth\.$", true, 2},
{"^<attacker> rips flesh off <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> tears deeply into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> rips <victim><vic_pl> <bodypart> to pieces with <a_his> teeth\.$", true, 2},
{"^<attacker> rends huge chunks of flesh from <victim><vic_pl> <bodypart>\.$", true, 2},
-- Pecky bird animals
{"^<attacker> pecks at <victim> with <a_his> beak\.$", true, 1},
{"^<attacker> snicks <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> scratches <victim><vic_pl> <bodypart> with <a_his> beak\.$", true, 2},
{"^<attacker> pecks <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> viciously pecks <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> gouges a hole in <victim><vic_pl> <bodypart> with <a_his> beak\.$", true, 2},
{"^<attacker> slices <victim><vic_pl> <bodypart> with <a_his> beak\.$", true, 2},
{"^<attacker> slices <victim><vic_pl> <bodypart> into small bits with <a_his> beak\.$", true, 2},
-- Nippy nasty bitey animals
{"^<attacker> attempts to bite <victim>\.$", true, 1},
{"^<attacker> nips <victim> in the <bodypart>\.$", true, 2},
{"^<attacker> nibbles at <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> bites <victim> in the <bodypart>\.$", true, 2},
{"^<attacker> sinks <a_his> teeth into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> bites into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> sinks <a_his> teeth deep into <victim><vic_pl> <bodypart>\.$", true, 2},
{"^<attacker> bites deeply into <victim><vic_pl> <bodypart>, splintering <v_his> bones\.$", true, 2},
-- Or fang equivalent
{"^<attacker> sinks <a_his> fangs deeply into <victim>\.$", true, 2},
-- Special attacks
-- Ramming weapons
{"^<attacker> (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )ramming <weapon> into <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> ramming <weapon> into <victim><vic_pl> <bodypart>(?> very weakly| weakly| very lightly| lightly| firmly| painfully| forcefully| stingingly| ferociously| brutally| devastatingly)?\.$", false, 1, true},
{"^<attacker> ramming <weapon> right through <victim><vic_pl> <bodypart>(?> very weakly| weakly| very lightly| lightly| firmly| painfully| forcefully| stingingly| ferociously| brutally| devastatingly)?\.$", false, 1, true},
-- Special kicks
{"^<attacker> swinging <a_his> foot upward to kick <victim> (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?in the <bodypart>\.$", false, 1, true},
{"^<attacker> raising <a_his> leg and stamping down (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?on <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> lifting <a_his> foot and stomping (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?on <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> swinging <a_his> foot to kick <victim> (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?in the <bodypart>\.$", false, 1, true},
{"^<attacker> spinning and landing a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?side kick on <victim><vic_pl> <bodypart>\.", false, 1, true},
-- Special punches
{"^<attacker> ducking to drive <a_his> fist (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?into <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> giving <victim> a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?punch to <v_his> <bodypart>\.$", false, 1, true},
{"^<attacker> giving <victim> a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?jab to the <bodypart>\.$", false, 1, true},
{"^<attacker> catching <victim> with a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?combination punch, delivered to the <bodypart>\.$", false, 1, true},
{"^<attacker> delivering a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?punch to <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> punching <victim> (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?in the <bodypart>\.$", false, 1, true},
{"^<attacker> catching <victim> with a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?uppercut\.$", false, 1, true},
{"^<attacker> hitting <victim> with a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?roundhouse punch to the <bodypart>\.$", false, 1, true},
-- Combo or punch/kick moves
{"^<attacker> driving <a_his> (?>fist|foot) (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?into <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> delivering a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?(?>jab|snap kick) to <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> landing a (?>very weak |weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?(?>punch in|kick on) <victim><vic_pl> <bodypart>\.$", false, 1, true},
{"^<attacker> hitting the side of <victim><vic_pl> <bodypart> (?>very weakly |weakly |very lightly |lightly |firmly |painfully |forcefully |stingingly |ferociously |brutally |devastatingly )?with a (?>roundhouse kick|cross)\.$", false, 1, true},
{"^<attacker> hitting <victim> (?>in|on) the <bodypart> with a (?>very weak |weak |very light |light |firm |painful |forceful |stinging |ferocious |brutal |devastating )?(?>punch|kick|roundhouse kick)\.$", false, 1, true},
}
-- No fancy regexing for these, just need converting to incoming, outgoing, and third party
local sStandaloneTexts = {
-- Ukulele
{"<WEAPON2> makes a dull sound through the air towards <victim>", 2, true},
{"You hear a clear C as <attacker> bash(es)? <victim><vic_pl> <bodypart> with <weapon>", 2},
-- Special hooter messages
{"<WEAPON2> produces such a loud noise, that <victim><vic_pl> eyes bulge out of <v_his> head", 2},
-- Worm sword, true at the end means it's a line that CAN be defended
{"<WEAPON2> slithers at <victim>", 2, true},
{"<WEAPON2> wobbles at <victim>", 2, true},
{"<WEAPON2> wiggles at <victim>", 2, true},
{"<WEAPON2> tentatively strokes <victim>", 2, true},
{"<WEAPON2> tickles <victim><vic_pl> <bodypart>", 2},
{"<WEAPON2> gently strokes <victim><vic_pl> <bodypart>", 2},
{"<WEAPON2> probes around in <victim><vic_pl> throat, looking for <v_his> tonsils", 2},
{"<WEAPON2> thrusts itself down <victim><vic_pl> throat, making it difficult for <v_him> to breathe", 2},
{"<WEAPON2> forces itself down <victim><vic_pl> throat and into <v_his> stomach", 2},
{"<WEAPON2> jams itself down <victim><vic_pl> throat, decimating <v_his> small intestine", 2},
{"<WEAPON2> wiggles through the air, wraps itself round <victim><vic_pl> <bodypart> and irritates <v_his> bits", 2},
{"<WEAPON2> wiggles through the air, wraps itself round <victim><vic_pl> <bodypart> and pulls <v_him> apart", 2},
{"<WEAPON2> whacks <victim> in the <bodypart>", 2},
{"<WEAPON2> lovingly wraps itself around <victim> and throttles <v_him>", 2},
{"<WEAPON2> enthusiastically wraps itself around <victim>, crushing <v_him>", 2},
{"<WEAPON2> wraps itself around the <victim> and crushes the life out of <v_him>", 2},
{"<WEAPON2> jumps down <victim><vic_pl> <bodypart>, suffocating <v_him> with nauseating slime", 2},
{"<WEAPON2> slithers over <victim><vic_pl> <bodypart>, leaving behind some disgusting slime", 2},
{"<WEAPON2> slithers (?>disgustingly|painfully) all over <victim><vic_pl> <bodypart>, (?>melting into|searing|burning|dripping slime on) <v_him>(?: with (?:acidic slime|its slimy bits))?", 2},
{"<WEAPON2> slithers (?>disgustingly|painfully) all over <victim><vic_pl> <bodypart>, scorching deep holes in <v_his> <bodypart> with acidic slime", 2},
{"<WEAPON2> twists itself into a wobbly arcane symbol\\. A dozen small worms pop their heads out of the ground and titter at <victim>", 2, true},
{"<WEAPON2> twists itself into an arcane symbol\\. A hundred small worms pop their heads out of the ground and attack <victim><vic_pl><bodypart>", 2},
{"<WEAPON2> twists itself into an arcane symbol\\. A few thousand large worms jump out of the ground and gnaw on <victim>", 2},
{"<WEAPON2> twists itself into an arcane symbol\\. A million and one HUGE worms jump out of the ground, swarm all over <victim>, and eat <v_him> alive", 2},
-- Below here are "Specials" (the 1 at the end), it means they count for special stats and CANNOT be defended atm (without some code change)
-- Sabre flicks
{"<ATTACKER> flicks? the point of <weapon> at <victim>, scoring a hit on", 1},
-- Feint
{"<ATTACKER> moves? as though about to launch a powerful attack on <victim>\\. <VICTIM> falls? for <a_his> feint, leaving <v_him> (?>momentarily )?off balance", 1},
{"<ATTACKER> moves? towards? <victim> as though about to launch a powerful attack\\. <VICTIM> prepares? to defend and, realising too late that it was just a feint, <v_is> left off balance", 1},
-- Shoves and trips
{"<ATTACKER> (?>shoves?|trips?) <victim>, (?>causing <v_him> to stumble(?: slightly)?|sending <v_him> crashing to the ground)", 1},
-- Crushing death specials
{"With a brutal swipe of <weapon2>, <victim> is mashed to the ground\\. <V_HIS> death throes are, unsurprisingly, short-lived", 1},
{"A final blow from <weapon2> tears <victim><vic_pl> jaw from <v_his> skull\\. Perhaps a closed casket would be best", 1},
{"<VICTIM><vic_pl> skull explodes beneath a powerful blow from <weapon2>, flinging blood, bone and brain several feet through the air, coating the area in gore and leaving a convulsing corpse on the ground\\. This is why <attacker2> never gets? hired as an interior decorator", 1},
{"<ATTACKER><at_pl> final blow with <weapon> hits <victim> with a sickening crunch as bones shatter, sending <v_him> sprawling lifelessly", 1},
{"As <victim> absorbs a blow from <weapon2>, <v_his> body gives way and folds like an accordion\\. Perhaps a skilled musician could play a triumphant jig on it", 1},
{"<WEAPON2> collides with <victim><vic_pl> body at such a speed that it reduces <v_his> carcass to a pulp of tissue, limbs and indeterminate organs\\. All that remain are\\.\\.\\. remains", 1},
{"<VICTIM> suffers the full brunt of a blow from <weapon2>, reducing <v_his> resulting cadaver to something more resembling a drawing by an angry child than anything once alive", 1},
{"Chunks of flesh are hurled into the air by the force of <attacker><at_pl> final swing of <weapon>, leaving <victim> in several bloody pieces on the ground\\. The gravedigger isn't going to be best pleased", 1},
{"As <weapon2> smash(es)? into <victim><vic_pl> stomach, <v_he> doubles over\\. The one thing learned from <v_his> death is that <v_he> had a kebab for supper", 1},
{"<ATTACKER> launch(es)? a powerful attack with <weapon>\\. Something between a squelch and a crunch emanates from <victim> as <v_his> corpse collapses in a graceless heap", 1},
{"<ATTACKER> turns? <victim><vic_pl> <bodypart> into a pulpy mess of flesh and bone with a powerful swing of <weapon>, killing <v_him> outright", 1},
{"<ATTACKER> launch(es)? a powerful attack with <weapon>\\. <victim> succumbs to <a_his> battery and dies, concave in all the wrong places", 1},
{"<ATTACKER> slams? <weapon> into <victim> with enough force to lift <v_him> a foot off the ground, spinning in a slow circle before <v_he> lands in a messy, bloodied heap", 1},
{"A series of sharp but muffled cracks can be heard as <victim><vic_pl> ribcage is pulverised by a crushing blow from <weapon2>", 1},
{"The top of <victim><vic_pl> skull collapses in on itself as <attacker> crush(es)? it with <weapon>, sending chunks of brain and bone splattering about", 1},
{"As <weapon2> connects, <victim> watch(es)? <v_his> ribs splinter and cave in, puncturing <v_his> lungs and other organs before <v_he> collapses? with a gurgle, flecks of bloody foam on <v_his> lips", 1},
{"<VICTIM> stumbles? as a colossal lump of stone is torn loose from <v_his> frame by <weapon2>\\. There is a long moment where nothing happens before <v_he> collapses? into a mound of rubble", 1},
{"<VICTIM> suddenly finds? <v_himself> much shorter \\(and significantly more dead\\) as <attacker> slams? <weapon> down on <v_his> <bodypart>", 1},
-- Impale death specials
{"As <attacker> drives? <weapon> into <victim><vic_pl> <bodypart> and yanks? it free, the wound spurts blood relentlessly, draining <v_his> last drops of life\\. Clean-up on aisle ", 1},
{"<ATTACKER> salutes? <victim> with <weapon> before driving it into <v_his> <bodypart> with a flick of <a_his> wrist", 1},
{"As <attacker> skewers? <v_him>, <victim> struggles? against <weapon> briefly, until gravity catches up to <v_him>, dragging <v_him> to the ground and off the weapon", 1},
{"<ATTACKER> fatally impales? <victim> on <weapon>, <v_his> lifeblood gushing from the wound as <a_he> withdraws? <a_his> weapon", 1},
{"<ATTACKER> runs? <weapon> right through <victim>, and <v_he> stands?, bleeding profusely, for a few seconds before collapsing lifelessly", 1},
{"<ATTACKER> skewers? <victim><vic_pl> <bodypart> with <weapon>, causing several jets of blood to spray out, covering the area in a fine red mist\\. In another medium, this might qualify as abstract art", 1},
{"<ATTACKER> shoves? <weapon> right through <victim><vic_pl> <bodypart>, the bloodied weapon bursting messily out the other side", 1},
{"<ATTACKER> bur(?>y|ies) <weapon> in <victim><vic_pl> <bodypart>, then pulls? it free with a pop like a cork escaping a bottle of champagne\\. However, instead of bubbly, a tide of gore erupts\\. Cheers", 1},
{"<ATTACKER> impales? <victim><vic_pl> <bodypart> with <weapon>, twisting it inside <v_him> before yanking it free\\. Un-skewered, <v_his> corpse slumps to the ground", 1},
{"<ATTACKER> launch(es)? a powerful attack with <weapon>\\. <victim> staggers? around, trying desperately to plug the hole in <v_his> <bodypart>\\. Maybe in <v_his> next life, <v_he>'ll make sure that <v_he> knows where <v_his> towel is", 1},
{"<ATTACKER> sheaths? <weapon> in <victim><vic_pl> eye\\. As <v_he> falls? to the ground, <a_he> withdraws? the weapon, wiping it clean before looking around for another opponent", 1},
{"<V_HIS> <bodypart> pierced by <weapon2>, <victim> hops? around briefly\\. Cradling <v_his> bleeding extremity, <v_he> falls? over, <v_his> screams ending as <v_he> collapses? to the ground", 1},
{"<ATTACKER> launch(es)? a powerful attack with <weapon>\\. For a moment, <attacker2> and <victim> stare at each other, before <victim2> collapses?, a gaping hole in <v_his> torso", 1},
{"<ATTACKER> plunges? <weapon> into <victim>\\. As it is withdrawn, <v_he> examines? the place where <v_his> <bodypart> used to be before slumping over lifelessly", 1},
{"As <victim> is impaled on <weapon2>, <v_his> innards burst from <v_his> body like grisly fireworks\\. At least <v_he> made an impression on the way out", 1},
{"<WEAPON2> travels halfway through <victim> before getting stuck in the stone\\. <VICTIM2> looks? triumphant, but only for a moment before <v_he> cracks? into (?>two|three|four|five|six|seven|eight|nine|ten) pieces", 1},
{"Managing to find a crack in <victim><vic_pl> skin, <attacker> plunges? <weapon> right into <v_him>, fatally wounding <v_him>", 1},
{"<ATTACKER> drives? <weapon> into <victim><vic_pl> trunk\\. The bark around <v_him> splinters and snaps\\. <VICTIM2> freezes? for a moment, looking far less animate as <v_he> dies?", 1},
{"With a flourish, <attacker> draws? back <weapon> and drives? it into <victim><vic_pl> <bodypart>", 1},
{"<ATTACKER> drives? <weapon> into <victim><vic_pl> <bodypart>, impaling <v_his> vital organs before it bursts out the other side in a shower of gore", 1},
{"<ATTACKER> steps? towards? <victim>, running <v_him> through with <weapon> in a single motion", 1},
{"<VICTIM> looks? down at <weapon3> protruding from <v_his> <bodypart> in horrified surprise, then back up at <attacker>, before the consequences catch up to <v_him> and <v_he> slumps? lifelessly to the ground", 1},
{"<ATTACKER> launch(es)? a powerful attack with <weapon>\\. <VICTIM> attempts? to say some last words as <weapon4> drives through <v_his> <bodypart>: ", 1},
}
-- Non-player animal/monster body part possibilities
local sAnimalParts =
{
"lower back", "upper back", "dorsal fin", "abdomen", "body", "breast", "thorax", "trunk", "tail", "branches",
"right rear paw", "left rear paw", "right rear foot", "left rear foot", "right front hoof", "left front hoof",
"right rear hoof", "left rear hoof", "right rear leg", "left rear leg", "right claw", "left claw",
"right back leg", "left back leg", "right front leg", "left front leg", "right petral fin", "left petral fin",
"right wing", "left wing", "right middle leg", "left middle leg", "right front paw", "left front paw",
}
local sAnimalBodyParts = ""
for iN, sPartname in ipairs(sAnimalParts) do
sAnimalBodyParts = sAnimalBodyParts .. sPartname .. "|"
end
sAnimalBodyParts = string.sub(sAnimalBodyParts, 0, -2)
-- And standard human body part possibilities
local sHumanParts =
{
"head", "skull", "face", "neck", "jaw", "chest", "back", "left arm", "guts", "left hand", "stomach", "shoulder",
"right arm", "right hand", "left leg", "left foot", "right leg", "right foot", "side", "ribs", "ribcage",
"left kneecap", "right kneecap", "solar plexus", "right leg's muscles", "left leg's muscles", "right arm's muscles", "left arm's muscles",
}
local sHumanBodyParts = ""
for iN, sPartname in ipairs(sHumanParts) do
sHumanBodyParts = sHumanBodyParts .. sPartname .. "|"
end
sHumanBodyParts = string.sub(sHumanBodyParts, 0, -2)
-- Fastest wildcard so far:
local sWild = "(?:\\w+\\b\\W*?){1,8}"
local sWildLong = "(?:\\w+\\b\\W*?){1,14}"
local iFlags = trigger_flag.Enabled + trigger_flag.RegularExpression
local bDebugTriggers = false
local sCatRegex
local sAttackStart
local sAttackEnding
local sAttackWeapon
local sAttackWeaponShort
local sAttackVictim
local sDefenseStart
local sDefenseEnding
local sDefenseWeapon
local sDefenseVictim
local sSpecialStart
local sSpecialEnding
local sSpecialWeapon
local sSpecialVictim
local iCategory
local sTempCut
local iVictim
local iBodypart
local sStringPart
local sTriggerName
local sTriggerFunction
local sTriggerColour
local sDefenseFunction
local sDefenseTrigger
local sBodyParts
for iIncOrOut = 1, 3 do
sCatRegex = {
[1] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[2] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[3] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[4] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[5] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[6] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[7] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
-- Special defense builders
[8] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[9] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[10] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[11] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[12] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[13] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[14] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
[15] = {
[1] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[2] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[3] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
[4] = {["string"] = "", ["words"] = {}, ["optional"] = false, ["count"] = 0, },
},
}
for iKey, sData in ipairs(sCombatTexts) do
-- Convert the string properly
if (sData[2] == false or iIncOrOut ~= 1) then
iCategory = 0
sTempCut = string.sub(sData[1], 12)
sTempCut = string.gsub(sTempCut, "<wild>", sWild)
if (iIncOrOut == 1) then
-- You (first person) are the attacker
sTempCut = string.gsub(sTempCut, "<vic_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<att_pl>", "r")
sTempCut = string.gsub(sTempCut, "<a_his>", "your")
sTempCut = string.gsub(sTempCut, "<a_himself>", "yourself")
sTempCut = string.gsub(sTempCut, "<v_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<v_him>", "(?>him|her|it)")
sTempCut = string.gsub(sTempCut, "<v_himself>", "(?>himself|herself|itself)")
elseif (iIncOrOut == 2) then
-- You (first person) are the victim
sTempCut = string.gsub(sTempCut, "<vic_pl>", "r")
sTempCut = string.gsub(sTempCut, "<att_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<a_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<a_himself>", "(?>himself|herself|itself)")
sTempCut = string.gsub(sTempCut, "<v_his>", "your")
sTempCut = string.gsub(sTempCut, "<v_him>", "you")
sTempCut = string.gsub(sTempCut, "<v_himself>", "yourself")
elseif (iIncOrOut == 3) then
-- You are not involved at all
sTempCut = string.gsub(sTempCut, "<vic_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<att_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<a_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<a_himself>", "(?>himself|herself|itself)")
sTempCut = string.gsub(sTempCut, "<v_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<v_him>", "(?>him|her|it)")
sTempCut = string.gsub(sTempCut, "<v_himself>", "(?>himself|herself|itself)")
end
iVictim = string.find(sTempCut, "<victim>", 1, true)
iBodypart = string.find(sTempCut, "<bodypart>", 1, true)
iWeapon = string.find(sTempCut, "<weapon>", 1, true)
sStringPart = {}
if (iBodypart ~= nil and iWeapon ~= nil and iVictim < iBodypart and iBodypart < iWeapon) then
iCategory = 1
sStringPart[1] = string.sub(sTempCut, 0, iVictim - 1)
sStringPart[2] = string.sub(sTempCut, iVictim + 8, iBodypart -1)
sStringPart[3] = string.sub(sTempCut, iBodypart + 10, iWeapon -1)
sStringPart[4] = string.sub(sTempCut, iWeapon + 8, -3)
elseif (iBodypart ~= nil and iWeapon ~= nil and iWeapon < iVictim and iVictim < iBodypart) then
iCategory = 2
sStringPart[1] = string.sub(sTempCut, 0, iWeapon -1)
sStringPart[2] = string.sub(sTempCut, iWeapon + 8, iVictim -1)
sStringPart[3] = string.sub(sTempCut, iVictim + 8, iBodypart -1)
sStringPart[4] = string.sub(sTempCut, iBodypart + 10, -3)
elseif (iBodypart == nil and iWeapon ~= nil and iVictim < iWeapon) then
iCategory = 6
sStringPart[1] = string.sub(sTempCut, 0, iVictim -1)
sStringPart[2] = string.sub(sTempCut, iVictim + 8, iWeapon -1)
sStringPart[3] = string.sub(sTempCut, iWeapon + 8, -3)
elseif (iWeapon == nil and iBodypart ~= nil and iVictim < iBodypart) then
iCategory = 3
sStringPart[1] = string.sub(sTempCut, 0, iVictim -1)
sStringPart[2] = string.sub(sTempCut, iVictim + 8, iBodypart -1)
sStringPart[3] = string.sub(sTempCut, iBodypart + 10, -3)
elseif (iWeapon ~= nil and iBodypart == nil and iWeapon < iVictim) then
iCategory = 7
sStringPart[1] = string.sub(sTempCut, 0, iWeapon -1)
sStringPart[2] = string.sub(sTempCut, iWeapon + 8, iVictim -1)
sStringPart[3] = string.sub(sTempCut, iVictim + 8, -3)
elseif (iWeapon == nil and iBodypart == nil and iVictim < (string.len(sTempCut) - 10)) then
iCategory = 4
sStringPart[1] = string.sub(sTempCut, 0, iVictim -1)
sStringPart[2] = string.sub(sTempCut, iVictim + 8, -3)
else
iCategory = 5
sStringPart[1] = string.sub(sTempCut, 0, iVictim -1)
sStringPart[2] = string.sub(sTempCut, iVictim + 8, -3)
end
--Note(iCategory .."=" .. sTempCut)
if (iIncOrOut == 1) then
-- Replace ies and hes to y and h... eg "parries"="parry", "crunches"="crunch", "tries"="try"
sStringPart[1] = string.gsub(sStringPart[1], "ies ", "y ")
sStringPart[1] = string.gsub(sStringPart[1], "hes ", "h ")
-- Remove S's at the end of a string but NOT if it's "ss" or "us", eg "mess" or "ferocious"... unpluralises them
sStringPart[1], iMatches = string.gsub(sStringPart[1], "([^su])s ", "%1 ")
end
-- Recovers the force-preserved S's
--[[
for iPart = 1, 4 do
if (sStringPart[iPart] ~= nil) then
sStringPart[iPart], iCount = string.gsub(sStringPart[iPart], "s$ ", "s ")
end
end
--]]
if (sData[4] == nil or sData[4] == false) then
for iPart = 1, 4 do
if (sStringPart[iPart] ~= nil) then
if (sCatRegex[iCategory][iPart]["words"][sStringPart[iPart]] == nil) then
sCatRegex[iCategory][iPart]["words"][sStringPart[iPart]] = sStringPart[iPart]
sCatRegex[iCategory][iPart]["count"] = sCatRegex[iCategory][iPart]["count"] + 1
if (sStringPart[iPart] == "") then
sCatRegex[iCategory][iPart]["optional"] = true
else
sCatRegex[iCategory][iPart]["string"] = sCatRegex[iCategory][iPart]["string"] .. sStringPart[iPart] .. "|"
end
end
end
end
end
-- Special texts
if (sData[4] ~= nil and sData[4] == true) then
local iSpecialCategory = 0
if (iCategory == 3) then
iSpecialCategory = 13
elseif (iCategory == 4) then
iSpecialCategory = 14
elseif (iCategory == 2) then
iSpecialCategory = 15
else
Note("Error missing category for SPECIAL=" .. iCategory .. " changed to " .. iSpecialCategory .. "=" .. sData[1])
end
for iPart = 1, 4 do
if (sStringPart[iPart] ~= nil) then
if (sCatRegex[iSpecialCategory][iPart]["words"][sStringPart[iPart]] == nil) then
sCatRegex[iSpecialCategory][iPart]["words"][sStringPart[iPart]] = sStringPart[iPart]
sCatRegex[iSpecialCategory][iPart]["count"] = sCatRegex[iSpecialCategory][iPart]["count"] + 1
if (sStringPart[iPart] == "") then
sCatRegex[iSpecialCategory][iPart]["optional"] = true
else
sCatRegex[iSpecialCategory][iPart]["string"] = sCatRegex[iSpecialCategory][iPart]["string"] .. sStringPart[iPart] .. "|"
end
end
end
end
end
-- Build defense lines for weak hits
if (sData[3] == 1 and sData[4] == nil) then
local iDefCategory = 0
if (iCategory == 4) then
iDefCategory = 8
elseif (iCategory == 3) then
iDefCategory = 9
elseif (iCategory == 5) then
iDefCategory = 10
elseif (iCategory == 6) then
iDefCategory = 11
elseif (iCategory == 7) then
iDefCategory = 12
else
Note("Error missing category for def=" .. iCategory .. " changed to " .. iDefCategory .. "=" .. sData[1])
end
for iPart = 1, 4 do
if (sStringPart[iPart] ~= nil) then
if (sCatRegex[iDefCategory][iPart]["words"][sStringPart[iPart]] == nil) then
sCatRegex[iDefCategory][iPart]["words"][sStringPart[iPart]] = sStringPart[iPart]
sCatRegex[iDefCategory][iPart]["count"] = sCatRegex[iDefCategory][iPart]["count"] + 1
if (sStringPart[iPart] == "") then
sCatRegex[iDefCategory][iPart]["optional"] = true
else
sCatRegex[iDefCategory][iPart]["string"] = sCatRegex[iDefCategory][iPart]["string"] .. sStringPart[iPart] .. "|"
end
end
end
end
end -- Defensive lines built
end -- if not an animal line
end -- Loop through all the "combattexts" table
-- Finish up the strings
for iCat, sCatData in ipairs(sCatRegex) do
for iPart, sPartData in ipairs(sCatData) do
if (sPartData["count"] > 1) then
sCatRegex[iCat][iPart]["string"] = "(?:" .. string.sub(sCatRegex[iCat][iPart]["string"], 1, -2) .. ")"
elseif (sPartData["count"] == 1) then
sCatRegex[iCat][iPart]["string"] = string.sub(sCatRegex[iCat][iPart]["string"], 1, -2)
end
if (sCatRegex[iCat][iPart]["optional"] == true and sCatRegex[iCat][iPart]["string"] ~= "") then
sCatRegex[iCat][iPart]["string"] = sCatRegex[iCat][iPart]["string"] .. "?"
end
end
end
if (iIncOrOut == 1) then
-- Outgoing attack BY you
sAttackSpecialStart = "^(?:> )?(?>You launch a powerful attack\\. You|Launching a powerful attack with a wild swing of your weapon, you|Launching a powerful wildswing attack on your adversaries, you|Swinging your weapon around wildly to launch a powerful attack, you|Unleashing a whirlwind of attacks on your adversaries, you|You launch a powerful attack and swing your weapon wildly\\. You|You spin your weapon in a wide arc and launch a powerful attack\\. You)"
sAttackStart = "^(?:> )?(?>You|(?>Exploiting (?>his|her|its) confusion|Catching (?>him|her|it) by surprise|Taking advantage of (?>his|her|its) surprise|Catching (?>him|her|it) off balance|Moving quickly|Quick as lightning|Moving too fast to see|In the blink of an eye|With a blur of speed|Striking like a cobra|Moving swiftly|With surprising speed|Repositioning yourself|With one last attack|Following through to the next opponent|Swinging your weapon around heavily|Continuing your wildswing attack|Continuing your attack|Using the momentum of your previous swing|Using your momentum to turn|Moving to your next target|In a final display of fighting power|Finishing your wildswing attack|With a final swing of your weapon|Turning to face your next opponent|Turning with the swing of your weapon|As you spin around), you)"
sAttackEnding = "(?: as " .. sWild .. " leaps in at the last moment to protect " .. sWild .. ")?( but (?>his|her|its) " .. sWild .. " absorbs (?>some|most) of the (?>blow|impact))?\\.$"
sAttackWeapon = "(?:one of )?your (?:" .. sWild .. ")"
sAttackWeaponShort = "(?:one of )?your (?:" .. sWild .. ")"
sAttackVictim = "(?:(?!you |you,|your )" .. sWild .. ")"
sDefenseSpecialStart = "^(?:> )?(?>You (?>attempt to launch|launch) a powerful attack\\. You|Launching a powerful attack with a wild swing of your weapon, you|Launching a powerful wildswing attack on your adversaries, you|Swinging your weapon around wildly to launch a powerful attack, you|Unleashing a whirlwind of attacks on your adversaries, you|You launch a powerful attack and swing your weapon wildly\\. You|You spin your weapon in a wide arc and launch a powerful attack\\. You)"
sDefenseStart = "^(?:> )?(?>You|(?>Exploiting (?>his|her|its) confusion|Catching (?>him|her|it) by surprise|Taking advantage of (?>his|her|its) surprise|Catching (?>him|her|it) off balance|Moving quickly|Moving too fast to see|Quick as lightning|In the blink of an eye|With a blur of speed|Striking like a cobra|Moving swiftly|With surprising speed|Repositioning yourself|With one last attack|Following through to the next opponent|Swinging your weapon around heavily|Continuing your wildswing attack|Continuing your attack|Using the momentum of your previous swing|Using your momentum to turn|Moving to your next target|In a final display of fighting power|Finishing your wildswing attack|With a final swing of your weapon|Turning to face your next opponent|Turning with the swing of your weapon|As you spin around), you)"
sDefenseEnding = "( as " .. sWild .. " leaps in at the last moment to protect " .. sWild .. ")? but( |, although unable to defend, | despite the surprise )(?:(?:(?>her |his |its )(?P<shielding>" .. sWildLong .. ") (?>swoops in and )?absorbs? all of the (?>blow|impact))|(?P<focus>you cannot seem to reach the place you are focusing on)|(?:he|she|" .. sWild .. ")(?P<level> barely| just| easily| deftly)?(?P<type> dodges out of the way| parries the blow with (?>his|her|its) " .. sWild .. "| blocks the blow with (?>his|her|its) " .. sWild .. "| somehow avoids the attack| deflects your lunge))\\.$"
sSpecialStart = "^(?:> )?You" .. " launch a powerful attack,"
--sBodyParts = sHumanBodyParts .. "|" .. sAnimalBodyParts
sBodyParts = "(?:\\w+\\b\\W*){1,4}"
sTriggerName = "QuowMeleeSuccessOutCat"
sTriggerFunction = "SuccessOutgoing"
sTriggerColour = "darkgoldenrod"
elseif (iIncOrOut == 2) then
-- Incoming attack against you
sAttackSpecialStart = "^(?:> )?(?!You )" .. sWild .. " launches a powerful attack\\. " .. sWild .. ""
-- This one might not be a hiephen off-balance?
sAttackStart = "^(?:> )?(?>Exploiting your confusion, |Catching you by surprise, |Taking advantage of your surprise, |Catching you off-balance, |Moving quickly, |Moving too fast to see, |Quick as lightning, |In the blink of an eye, |With a blur of speed, |Striking like a cobra, |Moving swiftly, |With surprising speed, )?(?:(?!You |you |The fire )" .. sWild .. ")"
sAttackEnding = "(?: as you leap in at the last moment to protect " .. sWild .. ")?(?: but your " .. sWild .. " absorbs (?>some|most) of the (?>blow|impact))?\\.$"
sAttackWeapon = "(?:one of )?(?>his|her|its) (?:" .. sWild .. ")"
sAttackWeaponShort = "(?:one of )?(?>his|her|its) (?:" .. sWild .. ")"
sAttackVictim = "you"
sDefenseSpecialStart = "^(?:> )?(?!You )" .. sWild .. " (?>attempts to launch|launches) a powerful attack\\. " .. sWild
-- Note: This one is definitely off-balance with a hiephen.
sDefenseStart = "^(?:> )?(?>Exploiting your confusion, |Catching you by surprise, |Taking advantage of your surprise, |Catching you off-balance, |Moving quickly, |Moving too fast to see, |Quick as lightning, |In the blink of an eye, |With a blur of speed, |Striking like a cobra, |Moving swiftly, |With surprising speed, )?(?:(?!You |you |The fire )" .. sWild .. ")"
sDefenseEnding = "(?: as you leap in at the last moment to protect " .. sWild .. ")? but( |, although unable to defend, | despite the surprise )(?:(?:your (?P<shielding>" .. sWildLong .. ") (?>swoops in and )?absorbs? all of the (?>blow|impact))|(?P<focus>(?>he |she |it )?cannot seem to reach the place (?>he|she|it) is focusing on)|you(?P<level> barely| just| easily| deftly)?(?P<type> dodge out of the way| parry the blow with your " .. sWild .. "| block the blow with your " .. sWild .. "| somehow avoid the attack| deflect (?>his|her|its) lunge))\\.$"
sSpecialStart = "^(?:> )?(?!You )" .. sWild .. " launches a powerful attack,"
--sBodyParts = sHumanBodyParts
sBodyParts = "(?:\\w+\\b\\W*){1,4}"
sTriggerName = "QuowMeleeSuccessIncCat"
sTriggerFunction = "SuccessIncoming"
sTriggerColour = "maroon"
elseif (iIncOrOut == 3) then
-- Witnessing an attack not involving you
sAttackSpecialStart = "^(?:> )?(?:Swinging (?>his|her|its) weapon around wildly to launch a powerful attack, (?!you )" .. sWild .. "|Launching a powerful attack with a wild swing of (?>his|her|its) weapon, (?!you )" .. sWild .. "|Launching a powerful wildswing attack, (?!you )" .. sWild .. "|Unleashing a whirlwind of attacks, (?!you )" .. sWild .. "|Spinning (?>his|her|its) weapon in a wide arc (?!you )" .. sWild .. " launches a powerful attack\\. " .. sWild .. "|(?!You )" .. sWild .. " launches a powerful attack\\. " .. sWild .. "|(?!You )" .. sWild .. " launches a powerful attack with a wild swing of (?>his|her|its) weapon\\. " .. sWild .. ")"
sAttackStart = "^(?:> )?(?>Exploiting (?>his|her|its) confusion, |Catching (?>him|her|it) by surprise, |Taking advantage of (?>his|her|its) surprise, |Catching (?>him|her|it) off balance, |Moving quickly, |Quick as lightning, |Moving too fast to see, |In the blink of an eye, |With a blur of speed, |Striking like a cobra, |Moving swiftly, |With surprising speed, |Repositioning (?>his|her|it)self, |With one last attack, |Following through to the next opponent, |Swinging (?>his|her|its) weapon around heavily, |Continuing (?>his|her|its) wildswing attack, |Continuing (?>his|her|its) attack, |Using the momentum of (?>his|her|its) previous swing, |Using (?>his|her|its) momentum to turn, |Moving to (?>his|her|its) next target, |In a final display of fighting power, |Finishing (?>his|her|its) wildswing attack, |With a final swing of (?>his|her|its) weapon, |Turning to face (?>his|her|its) next opponent, |Turning with the swing of (?>his|her|its) weapon, |As (?>he|she|it) spins around, )?(?:(?!You |you |The fire )" .. sWild .. ")"
sAttackEnding = "(?: as " .. sWild .. " leaps in at the last moment to protect " .. sWild .. ")?( but (?>his|her|its) " .. sWild .. " absorbs (?>some|most) of the (?>blow|impact))?\\.$"
sAttackWeapon = "(?:one of )?(?>his|her|its) (?:" .. sWild .. ")"
sAttackWeaponShort = "(?:one of )?(?>his|her|its) (?:" .. sWild .. ")"
sAttackVictim = "(?:(?!you |you,|your )" .. sWild .. ")"
sDefenseSpecialStart = "^(?:> )?(?:Swinging (?>his|her|its) weapon around wildly to launch a powerful attack, (?!you )" .. sWild .. "|Launching a powerful attack with a wild swing of (?>his|her|its) weapon, (?!you )" .. sWild .. "|Launching a powerful wildswing attack, (?!you )" .. sWild .. "|Unleashing a whirlwind of attacks, (?!you )" .. sWild .. "|Spinning (?>his|her|its) weapon in a wide arc (?!you )" .. sWild .. " launches a powerful attack\\. " .. sWild .. "|(?!You )" .. sWild .. " (?>attempts to launch|launches) a powerful attack\\. " .. sWild .. "|(?!You )" .. sWild .. " launches a powerful attack with a wild swing of (?>his|her|its) weapon\\. " .. sWild .. ")"
--sDefenseSpecialStart = "^(?:> )?(?!You )" .. sWild .. " (?>attempts to launch|launches) a powerful attack\\. " .. sWild
sDefenseStart = "^(?:> )?(?>Exploiting (?>his|her|its) confusion, |Catching (?>him|her|it) by surprise, |Taking advantage of (?>his|her|its) surprise, |Catching (?>him|her|it) off balance, |Moving quickly, |Quick as lightning, |Moving too fast to see, |In the blink of an eye, |With a blur of speed, |Striking like a cobra, |Moving swiftly, |With surprising speed, |Repositioning (?>his|her|it)self, |With one last attack, |Following through to the next opponent, |Swinging (?>his|her|its) weapon around heavily, |Continuing (?>his|her|its) wildswing attack, |Continuing (?>his|her|its) attack, |Using the momentum of (?>his|her|its) previous swing, |Using (?>his|her|its) momentum to turn, |Moving to (?>his|her|its) next target, |In a final display of fighting power, |Finishing (?>his|her|its) wildswing attack, |With a final swing of (?>his|her|its) weapon, |Turning to face (?>his|her|its) next opponent, |Turning with the swing of (?>his|her|its) weapon, |As (?>he|she|it) spins around, )?(?:(?!You |you |The fire )" .. sWild .. ")"
sDefenseEnding = "( as " .. sWild .. " leaps in at the last moment to protect " .. sWild .. ")? but( |, although unable to defend, | despite the surprise )(?:(?:(?>her |his |its )(?P<shielding>" .. sWildLong .. ") (?>swoops in and )?absorbs? all of the (?>blow|impact))|(?P<focus>(?>he |she |it )?cannot seem to reach the place (?>he|she|it) is focusing on)|(?:he|she|" .. sWild .. ")(?P<level> barely| just| easily| deftly)?(?P<type> dodges out of the way| parries the blow with (?>his|her|its) " .. sWild .. "| blocks the blow with (?>his|her|its) " .. sWild .. "| somehow avoids the attack| deflects (?>his|her|its) lunge))\\.$"
sSpecialStart = "^(?:> )?(?:(?!You )" .. sWild .. ") launches a powerful attack,"
--sBodyParts = sHumanBodyParts .. "|" .. sAnimalBodyParts
sBodyParts = "(?:\\w+\\b\\W*){1,4}"
sTriggerName = "StatsMeleeSuccessThirdCat"
sTriggerFunction = "" --"SuccessThird"
sTriggerColour = "#3C4420"
end
local sThisTriggerText = ""
--[[
Priorities/sequences:
50: You - specialling stuff + it being defended
60: You - hitting stuff + it being defended
70: You - specialling stuff
80: You - hitting stuff
100: Enemy - specialling you + it being defended
110: Enemy - hitting you + it being defended
120: Enemy - specialling you
130: Enemy - hitting you
150: Others - specialling others + it being defended
160: Others - hitting others + it being defended
170: Others - specialling others
180: Others - hitting others
--]]
local iUsePriority = 100
local sUseTriggerName = ""
local sUseTriggerFunction = ""
for iThisCat = 1, 7 do
for iThisSpecial = 1, 2 do
if (iThisCat == 1) then
sThisTriggerText = sCatRegex[1][1]["string"] .. sAttackVictim .. sCatRegex[1][2]["string"] .. "(?:" .. sBodyParts .. ")" .. sCatRegex[1][3]["string"] .. sAttackWeapon .. sCatRegex[1][4]["string"] .. sAttackEnding
elseif (iThisCat == 2) then
sThisTriggerText = sCatRegex[2][1]["string"] .. sAttackWeapon .. sCatRegex[2][2]["string"] .. sAttackVictim .. sCatRegex[2][3]["string"] .. "(?:" .. sBodyParts .. ")" .. sCatRegex[2][4]["string"] .. sAttackEnding
elseif (iThisCat == 3) then
sThisTriggerText = sCatRegex[3][1]["string"] .. sAttackVictim .. sCatRegex[3][2]["string"] .. "(?:" .. sBodyParts .. ")" .. sCatRegex[3][3]["string"] .. sAttackEnding
elseif (iThisCat == 4) then
sThisTriggerText = sCatRegex[4][1]["string"] .. sAttackVictim .. sCatRegex[4][2]["string"] .. sAttackEnding
elseif (iThisCat == 5) then
sTempCut = string.gsub(sCatRegex[5][2]["string"], "<weapon>", sAttackWeaponShort)
sTempCut = string.gsub(sTempCut, "<bodypart>", sBodyParts)
sThisTriggerText = sCatRegex[5][1]["string"] .. sAttackVictim .. sTempCut .. sAttackEnding
elseif (iThisCat == 6) then
sThisTriggerText = sCatRegex[6][1]["string"] .. sAttackVictim .. sCatRegex[6][2]["string"] .. sAttackWeapon .. sCatRegex[6][3]["string"] .. sAttackEnding
elseif (iThisCat == 7) then
sThisTriggerText = sCatRegex[7][1]["string"] .. sAttackWeapon .. sCatRegex[7][2]["string"] .. sAttackVictim .. sCatRegex[7][3]["string"] .. sAttackEnding
end
if (iThisSpecial == 1) then
sThisTriggerText = sAttackSpecialStart .. sThisTriggerText
sUseTriggerName = sTriggerName .. "Special" .. iThisCat
if (sTriggerFunction ~= "") then
sUseTriggerFunction = "StatsSpecial" .. sTriggerFunction
else
sUseTriggerFunction = ""
end
else
sThisTriggerText = sAttackStart .. sThisTriggerText
sUseTriggerName = sTriggerName .. iThisCat
if (sTriggerFunction ~= "") then
sUseTriggerFunction = "StatsMelee" .. sTriggerFunction
else
sUseTriggerFunction = ""
end
end
iUsePriority = (50 * iIncOrOut) + 10 + (iThisSpecial * 10) + iThisCat
iErrorCode = AddTriggerEx(tostring(sUseTriggerName), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sUseTriggerFunction), 12, iUsePriority)
if (iErrorCode ~= 0) then
Note(iErrorCode .. ": " .. sUseTriggerName .. "= " .. sThisTriggerText)
end
SetTriggerOption(tostring(sUseTriggerName), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sUseTriggerName), "custom_colour", tostring(17))
SetTriggerOption(tostring(sUseTriggerName), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sUseTriggerName .. " pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
end
end
-- Defensive line generation
if (iIncOrOut == 1) then
sTriggerName = "QuowMeleeFailOutCat"
sTriggerFunction = "FailOutgoing"
sTriggerColour = "maroon"
elseif (iIncOrOut == 2) then
sTriggerName = "QuowMeleeFailIncCat"
sTriggerFunction = "FailIncoming"
sTriggerColour = "olivedrab"
elseif (iIncOrOut == 3) then
sTriggerName = "StatsMeleeFailThirdCat"
sTriggerFunction = ""--"FailThird"
sTriggerColour = "darkgoldenrod"
end
sUseTriggerName = ""
sUseTriggerFunction = ""
for iThisCat = 1, 5 do
-- Category 1 defense lines are NOT used for you, because YOU cannot defend against YOURSELF!
if (iThisCat > 1 or iIncOrOut > 1) then
for iThisSpecial = 1, 2 do
if (iThisCat == 1) then
sThisTriggerText = sCatRegex[8][1]["string"] .. sAttackVictim .. sCatRegex[8][2]["string"] .. sDefenseEnding
elseif (iThisCat == 2) then
sThisTriggerText = sCatRegex[9][1]["string"] .. sAttackVictim .. sCatRegex[9][2]["string"] .. "(?:" .. sBodyParts .. ")" .. sCatRegex[9][3]["string"] .. sDefenseEnding
elseif (iThisCat == 3) then
sThisTriggerText2 = sCatRegex[10][1]["string"] .. sAttackVictim .. sDefenseEnding
sTempCut = string.gsub(sCatRegex[10][2]["string"], "<weapon>", sAttackWeaponShort)
sTempCut = string.gsub(sTempCut, "<bodypart>", sBodyParts)
sThisTriggerText = sCatRegex[10][1]["string"] .. sAttackVictim .. sTempCut .. sDefenseEnding
elseif (iThisCat == 4) then
sThisTriggerText = sCatRegex[11][1]["string"] .. sAttackVictim .. sCatRegex[11][2]["string"] .. sAttackWeapon .. sCatRegex[11][3]["string"] .. sDefenseEnding
elseif (iThisCat == 5) then
sThisTriggerText = sCatRegex[12][1]["string"] .. sAttackWeapon .. sCatRegex[12][2]["string"] .. sAttackVictim .. sCatRegex[12][3]["string"] .. sDefenseEnding
end
if (iThisSpecial == 1) then
sThisTriggerText = sDefenseSpecialStart .. sThisTriggerText
sUseTriggerName = sTriggerName .. "Special" .. iThisCat
if (sTriggerFunction ~= "") then
sUseTriggerFunction = "StatsSpecial" .. sTriggerFunction
else
sUseTriggerFunction = ""
end
else
sThisTriggerText = sDefenseStart .. sThisTriggerText
sUseTriggerName = sTriggerName .. iThisCat
if (sTriggerFunction ~= "") then
sUseTriggerFunction = "StatsMelee" .. sTriggerFunction
else
sUseTriggerFunction = ""
end
end
iUsePriority = (50 * iIncOrOut) + ((iThisSpecial - 1) * 10) + iThisCat
iErrorCode = AddTriggerEx(tostring(sUseTriggerName), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sUseTriggerFunction), 12, iUsePriority)
if (iErrorCode ~= 0) then
Note(iErrorCode .. ": " .. sUseTriggerName .. "= " .. sThisTriggerText)
end
SetTriggerOption(tostring(sUseTriggerName), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sUseTriggerName), "custom_colour", tostring(17))
SetTriggerOption(tostring(sUseTriggerName), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sUseTriggerName .. " pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
end
end
end
sUseTriggerFunction = ""
-- Special attacks successful
if (iIncOrOut == 1) then
sTriggerName = "QuowSpecialSuccessOutCat"
sTriggerFunction = "StatsSpecialSuccessOutgoing"
sTriggerColour = "darkgoldenrod"
elseif (iIncOrOut == 2) then
sTriggerName = "QuowSpecialSuccessIncCat"
sTriggerFunction = "StatsSpecialSuccessIncoming"
sTriggerColour = "maroon"
elseif (iIncOrOut == 3) then
sTriggerName = "StatsSpecialSuccessThirdCat"
sTriggerFunction = ""--"StatsSpecialSuccessThird"
sTriggerColour = "#3C4420"
end
iUsePriority = (50 * iIncOrOut) + 20 + 1
sThisTriggerText = sSpecialStart .. sCatRegex[13][1]["string"] .. sAttackVictim .. sCatRegex[13][2]["string"] .. "(?:" .. sBodyParts .. ")" .. sCatRegex[13][3]["string"] .. sAttackEnding
AddTriggerEx(tostring(sTriggerName .. "1"), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sTriggerFunction), 12, iUsePriority)
SetTriggerOption(tostring(sTriggerName .. "1"), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sTriggerName .. "1"), "custom_colour", tostring(17))
SetTriggerOption(tostring(sTriggerName .. "1"), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell("magenta", "", sTriggerName .. "1 pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
iUsePriority = (50 * iIncOrOut) + 20 + 2
sThisTriggerText = sSpecialStart .. sCatRegex[14][1]["string"] .. sAttackVictim .. sCatRegex[14][2]["string"] .. sAttackEnding
AddTriggerEx(tostring(sTriggerName .. "2"), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sTriggerFunction), 12, iUsePriority)
SetTriggerOption(tostring(sTriggerName .. "2"), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sTriggerName .. "2"), "custom_colour", tostring(17))
SetTriggerOption(tostring(sTriggerName .. "2"), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sTriggerName .. "2 pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
iUsePriority = (50 * iIncOrOut) + 20 + 3
sThisTriggerText = sSpecialStart .. sCatRegex[15][1]["string"] .. sAttackWeapon .. sCatRegex[15][2]["string"] .. sAttackVictim .. sCatRegex[15][3]["string"] .. "(?:" .. sBodyParts .. ")" .. sAttackEnding
AddTriggerEx(tostring(sTriggerName .. "3"), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sTriggerFunction), 12, iUsePriority)
SetTriggerOption(tostring(sTriggerName .. "3"), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sTriggerName .. "3"), "custom_colour", tostring(17))
SetTriggerOption(tostring(sTriggerName .. "3"), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sTriggerName .. "3 pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
-- Special attacks failed
if (iIncOrOut == 1) then
sTriggerName = "QuowSpecialFailOutCat"
sTriggerFunction = "StatsSpecialFailOutgoing"
sTriggerColour = "maroon"
elseif (iIncOrOut == 2) then
sTriggerName = "QuowSpecialFailIncCat"
sTriggerFunction = "StatsSpecialFailIncoming"
sTriggerColour = "olivedrab"
elseif (iIncOrOut == 3) then
sTriggerName = "StatsSpecialFailThirdCat"
sTriggerFunction = "" --"StatsSpecialFailThird"
sTriggerColour = "darkgoldenrod"
end
iUsePriority = (50 * iIncOrOut) + 1
-- Special defense generation
sThisTriggerText = sSpecialStart .. sCatRegex[13][1]["string"] .. sAttackVictim .. sCatRegex[13][2]["string"] .. "(?:" .. sBodyParts .. ")" .. sCatRegex[13][3]["string"] .. sDefenseEnding
AddTriggerEx(tostring(sTriggerName .. "1"), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sTriggerFunction), 12, iUsePriority)
SetTriggerOption(tostring(sTriggerName .. "1"), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sTriggerName .. "1"), "custom_colour", tostring(17))
SetTriggerOption(tostring(sTriggerName .. "1"), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell("magenta", "", sTriggerName .. "1 pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
iUsePriority = (50 * iIncOrOut) + 2
sThisTriggerText = sSpecialStart .. sCatRegex[14][1]["string"] .. sAttackVictim .. sCatRegex[14][2]["string"] .. sDefenseEnding
AddTriggerEx(tostring(sTriggerName .. "2"), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sTriggerFunction), 12, iUsePriority)
SetTriggerOption(tostring(sTriggerName .. "2"), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sTriggerName .. "2"), "custom_colour", tostring(17))
SetTriggerOption(tostring(sTriggerName .. "2"), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sTriggerName .. "2 pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
iUsePriority = (50 * iIncOrOut) + 3
sThisTriggerText = sSpecialStart .. sCatRegex[15][1]["string"] .. sAttackWeapon .. sCatRegex[15][2]["string"] .. sAttackVictim .. sCatRegex[15][3]["string"] .. "(?:" .. sBodyParts .. ")" .. sDefenseEnding
AddTriggerEx(tostring(sTriggerName .. "3"), tostring(sThisTriggerText), "", iFlags, -1, 0, "", tostring(sTriggerFunction), 12, iUsePriority)
SetTriggerOption(tostring(sTriggerName .. "3"), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sTriggerName .. "3"), "custom_colour", tostring(17))
SetTriggerOption(tostring(sTriggerName .. "3"), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sTriggerName .. "3 pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sThisTriggerText)
Note("")
end
end
--[[
Priorities/sequences:
50: You - specialling stuff + it being defended
60: You - hitting stuff + it being defended
70: You - specialling stuff
80: You - hitting stuff
100: Enemy - specialling you + it being defended
110: Enemy - hitting you + it being defended
120: Enemy - specialling you
130: Enemy - hitting you
150: Others - specialling others + it being defended
160: Others - hitting others + it being defended
170: Others - specialling others
180: Others - hitting others
--]]
-- Now loop through the "standalone" special texts
--sBodyParts = "(?:" .. sHumanBodyParts .. "|" .. sAnimalBodyParts .. ")"
sBodyParts = "(?:\\w+\\b\\W*){1,4}"
for iIncOrOut = 1, 3 do
iCustomCombatLinesNormal = 0
iCustomCombatLinesSpecial = 0
iCustomCombatLinesFailNormal = 0
--ColourNote("red", "", "=================== " .. tostring(iIncOrOut) .. "==================")
for iKey, sData in ipairs(sStandaloneTexts) do
sTempCut = sData[1]
if (iIncOrOut == 1) then
-- You (first person) are the attacker
sTempCut = string.gsub(sTempCut, "<ATTACKER>", "You")
sTempCut = string.gsub(sTempCut, "<attacker>", "you")
sTempCut = string.gsub(sTempCut, "<attacker2>", "you")
sTempCut = string.gsub(sTempCut, "<at_pl>", "r")
sTempCut = string.gsub(sTempCut, "<WEAPON>", "(?>One of your|Your) (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon>", "(?:one of )?your (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<WEAPON2>", "(?>One of your|Your) (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon2>", "(?:one of )?your (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon3>", "(?:one of )?(?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon4>", "(?:one of )?your (" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<VICTIM>", "(?:(?!You |You,|Your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<victim>", "(?:(?!you |you,|your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<VICTIM2>", "((?!You |You,|Your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<victim2>", "((?!you |you,|your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<vic_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<a_his>", "your")
sTempCut = string.gsub(sTempCut, "<a_he>", "you")
sTempCut = string.gsub(sTempCut, "<a_himself>", "yourself")
sTempCut = string.gsub(sTempCut, "<v_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<V_HIS>", "(?>His|Her|Its)")
sTempCut = string.gsub(sTempCut, "<v_him>", "(?>him|her|it)")
sTempCut = string.gsub(sTempCut, "<V_HE>", "(?>He|She|It)")
sTempCut = string.gsub(sTempCut, "<v_he>", "(?>he|she|it)")
sTempCut = string.gsub(sTempCut, "<v_is>", "is")
sTempCut = string.gsub(sTempCut, "<v_himself>", "(?>himself|herself|itself)")
elseif (iIncOrOut == 2) then
-- You (first person) are the victim
sTempCut = string.gsub(sTempCut, "<ATTACKER>", "(?:(?!You )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<attacker>", "(?:(?!you )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<attacker2>", "((?!you )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<at_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<WEAPON>", "(?>One of (?>his|her|its)|His|Her|Its) (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon>", "(?:one of )?(?>his|her|its) (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<WEAPON2>", "(?:One of )?(?:(?!Your )" .. sWild .. ")'s? (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon2>", "(?:one of )?(?:(?!your )" .. sWild .. ")'s? (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon3>", "(?:one of )?(?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon4>", "(?:one of )?((?!your )" .. sWild .. ")'s? (" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<VICTIM>", "You")
sTempCut = string.gsub(sTempCut, "<victim>", "you")
sTempCut = string.gsub(sTempCut, "<victim2>", "you")
sTempCut = string.gsub(sTempCut, "<VICTIM2>", "You")
sTempCut = string.gsub(sTempCut, "<vic_pl>", "r")
sTempCut = string.gsub(sTempCut, "<a_he>", "(?>he|she|it)")
sTempCut = string.gsub(sTempCut, "<a_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<a_himself>", "(?>himself|herself|itself)")
sTempCut = string.gsub(sTempCut, "<v_his>", "your")
sTempCut = string.gsub(sTempCut, "<V_HIS>", "Your")
sTempCut = string.gsub(sTempCut, "<v_him>", "you")
sTempCut = string.gsub(sTempCut, "<V_HE>", "You")
sTempCut = string.gsub(sTempCut, "<v_he>", "you")
sTempCut = string.gsub(sTempCut, "<v_is>", "are")
sTempCut = string.gsub(sTempCut, "<v_himself>", "yourself")
elseif (iIncOrOut == 3) then
-- You are not involved at all
sTempCut = string.gsub(sTempCut, "<ATTACKER>", "(?:(?!You )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<attacker>", "(?:(?!you )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<attacker2>", "((?!you )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<at_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<weapon>", "(?:one of )?(?>his|her|its) (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<WEAPON>", "(?>One of (?>his|her|its)|His|Her|Its) (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<WEAPON2>", "(?:One of )?(?:(?!Your )" .. sWild .. ")'s? (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon2>", "(?:one of )?(?:(?!your )" .. sWild .. ")'s? (?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon3>", "(?:one of )?(?:" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<weapon4>", "(?:one of )?((?!your )" .. sWild .. ")'s? (" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<VICTIM>", "(?:(?!You |You,|Your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<victim>", "(?:(?!you |you,|your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<VICTIM2>", "((?!You |You,|Your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<victim2>", "((?!you |you,|your )" .. sWild .. ")")
sTempCut = string.gsub(sTempCut, "<vic_pl>", "'s?")
sTempCut = string.gsub(sTempCut, "<a_he>", "(?>he|she|it)")
sTempCut = string.gsub(sTempCut, "<a_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<a_himself>", "(?>himself|herself|itself)")
sTempCut = string.gsub(sTempCut, "<v_his>", "(?>his|her|its)")
sTempCut = string.gsub(sTempCut, "<V_HIS>", "(?>His|Her|Its)")
sTempCut = string.gsub(sTempCut, "<v_him>", "(?>him|her|it)")
sTempCut = string.gsub(sTempCut, "<V_HE>", "(?>He|She|It)")
sTempCut = string.gsub(sTempCut, "<v_he>", "(?>he|she|it)")
sTempCut = string.gsub(sTempCut, "<v_is>", "is")
sTempCut = string.gsub(sTempCut, "<v_himself>", "(?>himself|herself|itself)")
end
sTempCut = string.gsub(sTempCut, "<bodypart>", sBodyParts)
sTempCut = "^(?:> )?" .. sTempCut
-- Special attacks succeeded
if (sData[2] == 1) then
iCustomCombatLinesSpecial = iCustomCombatLinesSpecial + 1
if (iIncOrOut == 1) then
sTriggerName = "QuowSpecialSuccessOutS" .. iCustomCombatLinesSpecial
sTriggerFunction = "StatsSpecialSuccessOutgoing"
sTriggerColour = "darkgoldenrod"
elseif (iIncOrOut == 2) then
sTriggerName = "QuowSpecialSuccessIncS" .. iCustomCombatLinesSpecial
sTriggerFunction = "StatsSpecialSuccessIncoming"
sTriggerColour = "maroon"
elseif (iIncOrOut == 3) then
sTriggerName = "StatsSpecialSuccessThirdS" .. iCustomCombatLinesSpecial
sTriggerFunction = ""--"StatsSpecialSuccessThird"
sTriggerColour = "#3C4420"
end
-- No other types here yet?
elseif (sData[2] == 2) then
iCustomCombatLinesNormal = iCustomCombatLinesNormal + 1
if (iIncOrOut == 1) then
sTriggerName = "QuowMeleeSuccessOutCat_Custom" .. iCustomCombatLinesNormal
sTriggerFunction = "StatsMeleeSuccessOutgoing"
sTriggerColour = "darkgoldenrod"
elseif (iIncOrOut == 2) then
sTriggerName = "QuowMeleeSuccessIncCat_Custom" .. iCustomCombatLinesNormal
sTriggerFunction = "StatsMeleeSuccessIncoming"
sTriggerColour = "maroon"
elseif (iIncOrOut == 3) then
sTriggerName = "StatsMeleeSuccessThirdCat_Custom" .. iCustomCombatLinesNormal
sTriggerFunction = "StatsMeleeSuccessThird"
sTriggerColour = "#3C4420"
end
end
-- Defensive parts to the custom line
if (sData[3] ~= nil and sData[3] == true) then
iCustomCombatLinesFailNormal = iCustomCombatLinesFailNormal + 1
if (iIncOrOut == 1) then
sDefenseEnding = ".*( as " .. sWild .. " leaps in at the last moment to protect " .. sWild .. ")? but( |, although unable to defend, | despite the surprise )(?:(?:(?>her |his |its )(?P<shielding>" .. sWildLong .. ") (?:swoops in and )?absorbs? all of the (?>blow|impact))|(?P<focus>you cannot seem to reach the place you are focusing on)|(?:he|she|" .. sWild .. ")(?P<level> barely| just| easily| deftly)?(?P<type> dodges out of the way| parries the blow with (?>his|her|its) " .. sWild .. "| blocks the blow with (?>his|her|its) " .. sWild .. "| somehow avoids the attack| deflects your lunge))\\.$"
sDefenseFunction = "StatsMeleeFailOutgoing"
sDefenseTrigger = "QuowMeleeFailOutCat_Custom" .. iCustomCombatLinesFailNormal
elseif (iIncOrOut == 2) then
sDefenseEnding = ".*(?: as you leap in at the last moment to protect " .. sWild .. ")? but( |, although unable to defend, | despite the surprise )(?:(?:your (?P<shielding>" .. sWildLong .. ") (?:swoops in and )?absorbs? all of the (?>blow|impact))|(?P<focus>(?>he |she |it )?cannot seem to reach the place (?>he|she|it) is focusing on)|you(?P<level> barely| just| easily| deftly)?(?P<type> dodge out of the way| parry the blow with your " .. sWild .. "| block the blow with your " .. sWild .. "| somehow avoid the attack| deflect (?>his|her|its) lunge))\\.$"
sDefenseFunction = "StatsMeleeFailIncoming"
sDefenseTrigger = "QuowMeleeFailIncCat_Custom" .. iCustomCombatLinesFailNormal
elseif (iIncOrOut == 3) then
sDefenseEnding = ".*( as " .. sWild .. " leaps in at the last moment to protect " .. sWild .. ")? but( |, although unable to defend, | despite the surprise )(?:(?:(?>her |his |its )(?P<shielding>" .. sWildLong .. ") (?:swoops in and )?absorbs? all of the (?>blow|impact))|(?P<focus>(?>he |she |it )?cannot seem to reach the place (?>he|she|it) is focusing on)|(?:he|she|" .. sWild .. ")(?P<level> barely| just| easily| deftly)?(?P<type> dodges out of the way| parries the blow with (?>his|her|its) " .. sWild .. "| blocks the blow with (?>his|her|its) " .. sWild .. "| somehow avoids the attack| deflects (?>his|her|its) lunge))\\.$"
sDefenseFunction = "StatsMeleeFailThird"
sDefenseTrigger = "StatsMeleeFailThirdCat_Custom" .. iCustomCombatLinesFailNormal
end
iUsePriority = 150 + (50 * iIncOrOut)
AddTriggerEx(tostring(sDefenseTrigger), tostring(sTempCut .. sDefenseEnding), "", iFlags, -1, 0, "", tostring(sDefenseFunction), 12, iUsePriority)
SetTriggerOption(tostring(sDefenseTrigger), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sDefenseTrigger), "custom_colour", tostring(17))
SetTriggerOption(tostring(sDefenseTrigger), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sDefenseTrigger .. " pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sTempCut .. sDefenseEnding)
Note("")
end
end
-- Special custom line
iUsePriority = 150 + (50 * iIncOrOut) + 20
AddTriggerEx(tostring(sTriggerName), tostring(sTempCut .. ".+?$"), "", iFlags, -1, 0, "", tostring(sTriggerFunction), 12, iUsePriority)
SetTriggerOption(tostring(sTriggerName), "group", "module_stats")
iTotalCombatTriggers = iTotalCombatTriggers + 1
SetTriggerOption(tostring(sTriggerName), "custom_colour", tostring(17))
SetTriggerOption(tostring(sTriggerName), "other_text_colour", tostring(ColourNameToRGB(sTriggerColour)))
if (bDebugTriggers == true) then
ColourTell(sGlobalColourOrange, "", sTriggerName .. " pri " .. iUsePriority .. "= ")
ColourNote(sTriggerColour, "", sTempCut)
Note("")
end
end -- Loop through standalone specials
end -- In or out 1-3
end
sQuowDefenseTypes = {
[0] = {"", "UNKNOWN ERROR?"},
[1] = {"defended_dodged", "Dodge"},
[2] = {"defended_parried", "Parry"},
[3] = {"defended_blocked", "Block"},
[4] = {"armoured", "Armour"},
[5] = {"tpa", "TPA"},
[6] = {"bugs", "Bug Shield"},
[7] = {"major", "Major Shield"},
[8] = {"ccc", "CCC"},
[9] = {"eff", "EFF"},
}
sQuowDefenseLevels = {
[0] = {"", "UNKNOWN ERROR?"},
[1] = {"barely", "Bad"},
[2] = {"normal", "Normal"},
[3] = {"deftly", "Good"},
[4] = {"somehow", "Somehow Avoids"},
}
sQuowAbsorbTypes = {
["magical shielding"] = 5,
["wall of dust"] = 7,
["cloak of fog"] = 7,
["layer of fluff"] = 7,
["feathery skin"] = 7,
["slimy cloak"] = 7,
["holy olive wool vestment"] = 7,
["flaming barrier"] = 7,
["chalky skin"] = 8,
["elastic skin"] = 8,
["metallic skin"] = 8,
}
-- Convert the trigger into defensive types and levels
function GetDefensiveType(sDefenseWildcard, sLevelWildcard, sShieldingWildcard)
if (sDefenseWildcard == nil) then
sDefenseWildcard = ""
end
if (sShieldingWildcard == nil) then
sShieldingWildcard = ""
end
if (sLevelWildcard == nil) then
sLevelWildcard = ""
end
local iLevel = 0
local iDefense = 0
--Note("Shielding='" .. sShieldingWildcard .. "', Defensing='" .. sDefenseWildcard .. "', Level='" .. sLevelWildcard .. "'")
if (string.sub(sDefenseWildcard, 1, 6) == " dodge") then
iDefense = 1
iLevel = 2
elseif (string.sub(sDefenseWildcard, 1, 5) == " parr" or string.sub(sDefenseWildcard, 1, 8) == " deflect") then
iDefense = 2
iLevel = 2
elseif (string.sub(sDefenseWildcard, 1, 6) == " block") then
iDefense = 3
iLevel = 2
elseif (string.sub(sDefenseWildcard, 1, 14) == " somehow avoid") then
iDefense = 1
iLevel = 4
elseif (string.sub(sShieldingWildcard, 1, 9) == "floating ") then
-- Wizard or Witch EFF
iDefense = 9
elseif (sQuowAbsorbTypes[sShieldingWildcard] ~= nil) then
-- TPA, Major Shields, CCC
iDefense = sQuowAbsorbTypes[sShieldingWildcard]
elseif (string.sub(sShieldingWildcard, 1, 11) == "handful of " or string.sub(sShieldingWildcard, 1, 9) == "cloud of " or string.sub(sShieldingWildcard, 1, 15) == "small swarm of " or string.sub(sShieldingWildcard, 1, 15) == "large swarm of " or string.sub(sShieldingWildcard, 1, 14) == "vast swarm of " or string.sub(sShieldingWildcard, 1, 10) == "plague of ") then
-- Witch bug shield
iDefense = 6
elseif (sShieldingWildcard ~= "") then
-- Anything else is treated as physical armour (even if it's a combo, eg minor shield + security blanket)
iDefense = 4
end
if (sLevelWildcard == " just" or sLevelWildcard == " barely") then
iLevel = 1
elseif (sLevelWildcard == " easily" or sLevelWildcard == " deftly" or sLevelWildcard == " quickly" or sLevelWildcard == " swiftly") then
iLevel = 3
end
return iDefense, iLevel
end
function StatAddDefenseCalcIncoming(wildcards)
-- Was this a zonefail, or some other kind of defense maybe
if (wildcards.focus ~= nil and wildcards.focus ~= "") then
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_zonefail"] + 1
elseif ((wildcards.type ~= nil and wildcards.type ~= "") or (wildcards.shielding ~= nil and wildcards.shielding ~= "")) then
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_defended"] + 1
local iThisDefense = 0
local iThisLevel = 0
iThisDefense, iThisLevel = GetDefensiveType(wildcards.type, wildcards.level, wildcards.shielding)
local sThisStat = "hits_inc_" .. sQuowDefenseTypes[iThisDefense][1]
iQuowCombatStats[iCurrentCombatStatSet][sThisStat] = iQuowCombatStats[iCurrentCombatStatSet][sThisStat] + 1
if (iThisLevel > 0) then
sThisStat = sThisStat .. "_" .. sQuowDefenseLevels[iThisLevel][1]
iQuowCombatStats[iCurrentCombatStatSet][sThisStat] = iQuowCombatStats[iCurrentCombatStatSet][sThisStat] + 1
end
end
end
function StatAddDefenseCalcOutgoing(wildcards)
-- Was this a zonefail, or some other kind of defense maybe
if (wildcards.focus ~= nil and wildcards.focus ~= "") then
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_zonefail"] + 1
elseif ((wildcards.type ~= nil and wildcards.type ~= "") or (wildcards.shielding ~= nil and wildcards.shielding ~= "")) then
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_defended"] + 1
local iThisDefense = 0
local iThisLevel = 0
iThisDefense, iThisLevel = GetDefensiveType(wildcards.type, wildcards.level, wildcards.shielding)
local sThisStat = "hits_out_" .. sQuowDefenseTypes[iThisDefense][1]
iQuowCombatStats[iCurrentCombatStatSet][sThisStat] = iQuowCombatStats[iCurrentCombatStatSet][sThisStat] + 1
if (iThisLevel > 0) then
sThisStat = sThisStat .. "_" .. sQuowDefenseLevels[iThisLevel][1]
iQuowCombatStats[iCurrentCombatStatSet][sThisStat] = iQuowCombatStats[iCurrentCombatStatSet][sThisStat] + 1
end
end
end
-- OUTGOING: A DEFENDED/BLOCKED hit
function StatsMeleeFailOutgoing(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] + 1
StatAddDefenseCalcOutgoing(wildcards)
--RedrawStatsWindow()
end
-- INCOMING: A DEFENDED/BLOCKED hit
function StatsMeleeFailIncoming(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] + 1
StatAddDefenseCalcIncoming(wildcards)
--RedrawStatsWindow()
end
-- Third-Party: A DEFENDED/BLOCKED hit
function StatsMeleeFailThird(sName, sLine, wildcards)
-- Function currently disabled in regex generation
end
-- OUTGOING: A DEFENDED Special
function StatsSpecialFailOutgoing(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["special_out_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["special_out_defended"] + 1
StatAddDefenseCalcOutgoing(wildcards)
--RedrawStatsWindow()
end
-- INCOMING: A DEFENDED Special
function StatsSpecialFailIncoming(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["special_inc_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["special_inc_defended"] + 1
StatAddDefenseCalcIncoming(wildcards)
--RedrawStatsWindow()
end
-- Third-Party: A DEFENDED Special
function StatsSpecialFailThird(sName, sLine, wildcards)
-- Function currently disabled in regex generation
end
-- OUTGOING: A SUCCESFUL hit (did not get dodged, blocked, parried, or fully absorbed - partial hits count as successful hits!)
function StatsMeleeSuccessOutgoing(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] + 1
--RedrawStatsWindow()
end
-- INCOMING: A SUCCESFUL hit (did not get dodged, blocked, parried, or fully absorbed - partial hits count as successful hits!)
function StatsMeleeSuccessIncoming(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] + 1
--RedrawStatsWindow()
end
-- Third-Party: A SUCCESFUL hit (did not get dodged, blocked, parried, or fully absorbed - partial hits count as successful hits!)
function StatsMeleeSuccessThird(sName, sLine, wildcards)
-- Function currently disabled in regex generation
end
-- OUTGOING: A SUCCESFUL Special
function StatsSpecialSuccessOutgoing(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_total"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_out_landed"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["special_out_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["special_out_landed"] + 1
--RedrawStatsWindow()
end
-- INCOMING: A SUCCESFUL Special
function StatsSpecialSuccessIncoming(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_total"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["hits_inc_landed"] + 1
iQuowCombatStats[iCurrentCombatStatSet]["special_inc_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["special_inc_landed"] + 1
--RedrawStatsWindow()
end
-- Third-Party: A SUCCESFUL Special
function StatsSpecialSuccessThird(sName, sLine, wildcards)
-- Function currently disabled in regex generation
end
-- OUTGOING: A SUCCESFUL Special, but no hits
function StatsSpecialSuccessNoHitOutgoing(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["special_out_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["special_out_landed"] + 1
--RedrawStatsWindow()
end
-- INCOMING: A SUCCESFUL Special, but no hits
function StatsSpecialSuccessNoHitIncoming(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["special_inc_landed"] = iQuowCombatStats[iCurrentCombatStatSet]["special_inc_landed"] + 1
--RedrawStatsWindow()
end
-- Third-Party: A SUCCESFUL Special, but no hits
function StatsSpecialSuccessNoHitThird(sName, sLine, wildcards)
-- Function currently disabled in regex generation
end
-- OUTGOING: A DEFENDED Special, but no hits
function StatsSpecialFailNoHitOutgoing(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["special_out_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["special_out_defended"] + 1
--RedrawStatsWindow()
end
-- INCOMING: A DEFENDED Special, but no hits
function StatsSpecialFailNoHitIncoming(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["special_inc_defended"] = iQuowCombatStats[iCurrentCombatStatSet]["special_inc_defended"] + 1
--RedrawStatsWindow()
end
-- Third-Party: A DEFENDED Special, but no hits
function StatsSpecialFailNoHitThird(sName, sLine, wildcards)
-- Function currently disabled in regex generation
end
-- You (player) failed to prepare a special.
function StatsSpecialPrepareFail(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["special_out_failprepared"] = iQuowCombatStats[iCurrentCombatStatSet]["special_out_failprepared"] + 1
--RedrawStatsWindow()
end
-- You (player) preparing a special.
function StatsSpecialPrepareSuccess(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["special_out_prepared"] = iQuowCombatStats[iCurrentCombatStatSet]["special_out_prepared"] + 1
--RedrawStatsWindow()
end
-- You killed something
function StatsKillStatOutgoing(sName, sLine, wildcards)
-- Temporary group kill stat
if (sGroupMembers[sMyPlayerName] ~= nil) then
sGroupMembers[sMyPlayerName]["Kills"] = sGroupMembers[sMyPlayerName]["Kills"] + 1
end
-- Main stat
iQuowCombatStats[iCurrentCombatStatSet]["kills_total"] = iQuowCombatStats[iCurrentCombatStatSet]["kills_total"] + 1
RedrawStatsWindow()
end
-- You got killed by something
function StatsKillStatIncoming(sName, sLine, wildcards)
iQuowCombatStats[iCurrentCombatStatSet]["deaths_total"] = iQuowCombatStats[iCurrentCombatStatSet]["deaths_total"] + 1
RedrawStatsWindow()
end
-- Third party killing something else
function StatsKillStatThird(sName, sLine, wildcards)
-- Group kill stats
sUsePlayerName = FilterPlayerName(wildcards.att)
if (sUsePlayerName ~= nil) then
sGroupMembers[sUsePlayerName]["Kills"] = sGroupMembers[sUsePlayerName]["Kills"] + 1
end
end
-- ******************************
-- ***** Auto GP Regenerate *****
-- ******************************
-- Update the user's GP bar each heartbeat
function UpdateGPGeneration()
if (iCharVitals["gp"] < iCharVitals["maxgp"] and iQuowCombatStats[iCurrentCombatStatSet]["gp_regen"] > 0) then
iCharVitals["gp"] = iCharVitals["gp"] + iQuowCombatStats[iCurrentCombatStatSet]["gp_regen"]
if (iCharVitals["gp"] > iCharVitals["maxgp"]) then
iCharVitals["gp"] = iCharVitals["maxgp"]
end
RedrawVitalsWindow()
Repaint()
end
end
-- Watching for players logging on, so we can switch combat sets automatically if desired
function HandleLoginNotification(sName, sLine, wildcards)
for iN = 1, 5 do
if (wildcards.login == iQuowCombatStats[iN]["set_name"]) then
iCurrentCombatStatSet = iN
RedrawStatsWindow()
ColourNote(sGlobalColourOrange, "", "Quow's Cow Bar automatically switching to combat set named: '" .. wildcards.login .. "'")
end
end
end
-- Filter through possible titles and family names finding a valid group member name, or return nil if none found
function FilterPlayerName(sPlayerName)
sPlayerName = string.gsub (sPlayerName, "%f[%a].", string.upper)
-- Check we don't already have a perfectly valid name without any edits
if (sGroupMembers[sPlayerName] ~= nil) then
return sPlayerName
end
-- Loop through the individual words, and find one that matches a group member
for sCutName in string.gmatch(sPlayerName, "%w+") do
if (sGroupMembers[sCutName] ~= nil) then
return sCutName
end
end
return nil
end
-- Found your name and exact stats for the group
function HandleGroupStatusMe(sName, sLine, wildcards)
-- wildcards.player
sMyPlayerName = wildcards.player
if (sGroupMembers[wildcards.player] == nil) then
sGroupMembers[wildcards.player] = {["HP"] = sGroupMembers["You"]["HP"], ["GP"] = sGroupMembers["You"]["GP"], ["TPA"] = sGroupMembers["You"]["TPA"], ["CCC"] = sGroupMembers["You"]["CCC"], ["EFF"] = sGroupMembers["You"]["EFF"], ["KII"] = sGroupMembers["You"]["KII"], ["MS"] = sGroupMembers["You"]["MS"], ["MemberSince"] = os.time(), ["Kills"] = 0}
else
sGroupMembers[wildcards.player]["HP"] = sGroupMembers["You"]["HP"]
sGroupMembers[wildcards.player]["GP"] = sGroupMembers["You"]["GP"]
end
RedrawShieldsWindow()
Redraw()
end
-- Name, rough health status and rough GP status of another group member
function HandleGroupStatusOther(sName, sLine, wildcards)
local iHP = 0
local iGP = 0
if (wildcards.hp == "unhurt") then
iHP = 100
elseif (wildcards.hp == "almost unhurt") then
iHP = 95
elseif (wildcards.hp == "scratched") then
iHP = 90
elseif (wildcards.hp == "slightly hurt") then
iHP = 80
elseif (wildcards.hp == "slightly injured") then
iHP = 70
elseif (wildcards.hp == "injured") then
iHP = 60
elseif (wildcards.hp == "slightly wounded") then
iHP = 50
elseif (wildcards.hp == "wounded") then
iHP = 40
elseif (wildcards.hp == "badly wounded") then
iHP = 30
elseif (wildcards.hp == "heavily wounded") then
iHP = 20
elseif (wildcards.hp == "seriously wounded") then
iHP = 15
elseif (wildcards.hp == "critically wounded") then
iHP = 10
elseif (wildcards.hp == "near death") then
iHP = 5
end
if (wildcards.gp == "refreshed") then
iGP = 100
elseif (wildcards.gp == "clear of mind") then
iGP = 90
elseif (wildcards.gp == "concentrated") then
iGP = 80
elseif (wildcards.gp == "slightly confused") then
iGP = 70
elseif (wildcards.gp == "confused") then
iGP = 60
elseif (wildcards.gp == "slightly fatigued") then
iGP = 50
elseif (wildcards.gp == "fatigued") then
iGP = 40
elseif (wildcards.gp == "very fatigued") then
iGP = 30
elseif (wildcards.gp == "highly fatigued") then
iGP = 20
elseif (wildcards.gp == "severely fatigued") then
iGP = 10
elseif (wildcards.gp == "near unconscious") then
iGP = 5
end
if (sGroupMembers[wildcards.player] == nil) then
sGroupMembers[wildcards.player] = {["HP"] = iHP, ["GP"] = iGP, ["TPA"] = 0, ["CCC"] = 0, ["EFF"] = 0, ["KII"] = 0, ["MS"] = 0, ["MemberSince"] = os.time(), ["Kills"] = 0}
else
sGroupMembers[wildcards.player]["HP"] = iHP
sGroupMembers[wildcards.player]["GP"] = iGP
end
RedrawShieldsWindow()
Redraw()
end
-- You join a group
function HandleGroupJoinMe(sName, sLine, wildcards)
-- wildcards.groupname
end
-- You leave a group
function HandleGroupLeaveMe(sName, sLine, wildcards)
-- wildcards.groupname
for sCharacterName, sGroupData in pairs(sGroupMembers) do
if (sCharacterName ~= "You") then
sGroupMembers[sCharacterName] = nil
end
end
RedrawShieldsWindow()
Redraw()
end
-- Someone joins your group
function HandleGroupJoinOther(sName, sLine, wildcards)
-- wildcards.groupname
-- wildcards.player
wildcards.player = string.gsub(wildcards.player, "%f[%a].", string.upper)
if (sGroupMembers[wildcards.player] == nil) then
sGroupMembers[wildcards.player] = {["HP"] = 0, ["GP"] = 0, ["TPA"] = 0, ["CCC"] = 0, ["EFF"] = 0, ["KII"] = 0, ["MS"] = 0, ["MemberSince"] = os.time(), ["Kills"] = 0}
RedrawShieldsWindow()
Redraw()
end
end
-- Someone leaves your group
function HandleGroupLeaveOther(sName, sLine, wildcards)
-- wildcards.groupname
-- wildcards.player
wildcards.player = string.gsub(wildcards.player, "%f[%a].", string.upper)
if (sGroupMembers[wildcards.player] ~= nil) then
sGroupMembers[wildcards.player] = nil
RedrawShieldsWindow()
Redraw()
end
end
-- Recording your own personal shields
function HandleArcaneTriggerMe(sName, sLine, wildcards)
iArcaneGatherLastSaw = os.time()
sArcaneGatherPlayerSeen = "You"
sGroupMembers[sArcaneGatherPlayerSeen]["TPA"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["CCC"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["EFF"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["KII"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["MS"] = 0
-- If we're part of a group, then record this as a group thing
if (sGroupMembers[sMyPlayerName] ~= nil) then
sArcaneGatherPlayerSeen = sMyPlayerName
sGroupMembers[sArcaneGatherPlayerSeen]["TPA"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["CCC"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["EFF"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["KII"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["MS"] = 0
end
end
-- Recording a players arcane shields
sArcaneGatherPlayerSeen = ""
iArcaneGatherLastSaw = 0
function HandleArcaneTriggerOther(sName, sLine, wildcards)
if (wildcards.player ~= nil and wildcards.player ~= "") then
wildcards.player = string.gsub(wildcards.player, "%f[%a].", string.upper)
iArcaneGatherLastSaw = os.time()
sArcaneGatherPlayerSeen = wildcards.player
if (sGroupMembers[sArcaneGatherPlayerSeen] == nil) then
sGroupMembers[sArcaneGatherPlayerSeen] = {["HP"] = 0, ["GP"] = 0, ["TPA"] = 0, ["CCC"] = 0, ["EFF"] = 0, ["KII"] = 0, ["MS"] = 0, ["MemberSince"] = os.time(), ["Kills"] = 0}
else
sGroupMembers[sArcaneGatherPlayerSeen]["TPA"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["CCC"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["EFF"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["KII"] = 0
sGroupMembers[sArcaneGatherPlayerSeen]["MS"] = 0
if (sArcaneGatherPlayerSeen == sMyPlayerName) then
sGroupMembers["You"]["TPA"] = 0
sGroupMembers["You"]["CCC"] = 0
sGroupMembers["You"]["EFF"] = 0
sGroupMembers["You"]["KII"] = 0
sGroupMembers["You"]["MS"] = 0
end
end
RedrawShieldsWindow()
Redraw()
end
end
-- Recording a shield type
function HandleShieldData(sName, sLine, wildcards)
local bNeedUpdate = false
local sMessageType = string.sub(sName, -7, -5)
local sShieldType = string.sub(sName, -3)
-- Major shield string is shorter
if (sShieldType == "_MS") then
sShieldType = "MS"
end
--Note(sName .. ": Shield for " .. sShieldType .. " [" .. sArcaneGatherPlayerSeen .. "]" .. tostring(wildcards.player))
-- Make sure we've got a valid playername that was seen in the last few moments if appropriate
local sUsePlayerName
if (sMessageType == "YNU") then
-- You, shield up
bNeedUpdate = true
sGroupMembers["You"][sShieldType] = 100
if (sGroupMembers[sMyPlayerName] ~= nil) then
sGroupMembers[sMyPlayerName][sShieldType] = 100
end
elseif (sMessageType == "YND") then
-- You, shield down
bNeedUpdate = true
sGroupMembers["You"][sShieldType] = 0
if (sGroupMembers[sMyPlayerName] ~= nil) then
sGroupMembers[sMyPlayerName][sShieldType] = 0
end
elseif (sMessageType == "ONU") then
-- Other person, shield ups
sUsePlayerName = FilterPlayerName(wildcards.player)
if (sUsePlayerName == nil) then
return
end
if (sGroupMembers[sUsePlayerName] ~= nil) then
bNeedUpdate = true
sGroupMembers[sUsePlayerName][sShieldType] = 100
end
elseif (sMessageType == "OND") then
-- Other person, shield down
sUsePlayerName = FilterPlayerName(wildcards.player)
if (sUsePlayerName == nil) then
return
end
if (sGroupMembers[sUsePlayerName] ~= nil) then
bNeedUpdate = true
sGroupMembers[sUsePlayerName][sShieldType] = 0
end
elseif (sArcaneGatherPlayerSeen ~= "" and os.time() - iArcaneGatherLastSaw < 2) then
sGroupMembers[sArcaneGatherPlayerSeen][sShieldType] = 100
if (sArcaneGatherPlayerSeen == sMyPlayerName) then
sGroupMembers["You"][sShieldType] = 100
end
bNeedUpdate = true
end
if (bNeedUpdate == true) then
RedrawShieldsWindow()
Redraw()
end
end
-- Create triggers for any desired talker channels
for sKey, sData in pairs(objChatFilters) do
if (sKey ~= "Tells_In" and sKey ~= "Tells_Out" and sKey ~= "Group_Say") then
local iThisFlags = 33
if (sData[3] == true) then
iThisFlags = iThisFlags + 4
end
local sThisTrigger = "CommLog_" .. string.gsub(sKey, "-", "_ZXA_")
AddTriggerEx(sThisTrigger, "^(?:> )?\\((?P<channel>" .. string.gsub(sKey, "_", " ") .. ")\\) [A-Za-z](?:\\w+\\b\\W*?){1,8}", "", iThisFlags, -1, 0, "", "HandleCommsMessage", 12, 4)
SetTriggerOption(sThisTrigger, "group", "module_comms")
elseif (sKey == "Group_Say" and sData[3] == true) then
SetTriggerOption("CommLog_Group_Say", "omit_from_output", "y")
end
end
-- Combat Spam Additions
local combat_spam_flag = "y"
function ToggleCombatSpam()
combat_spam_flag = ((combat_spam_flag ~= "y") and "y" or "n")
---
sUSER_OPTIONS["omit_melee_out_fail"] = combat_spam_flag
sUSER_OPTIONS["omit_melee_inc_fail"] = combat_spam_flag
sUSER_OPTIONS["omit_melee_third_fail"] = combat_spam_flag
CallPlugin("bfe35205f026786ea1d56e3b", "TriggersShowHide", "", "")
Note("Combat Spam Hidden: " .. combat_spam_flag)
end
]]>
</script>
<!-- Triggers -->
<triggers>
<!-- ASCII Map Redirection -->
<trigger
enabled="n"
keep_evaluating="y"
match="*"
regexp="n"
omit_from_output="n"
sequence="1"
name="AsciiMapPre"
group="module_ascii"
send_to="12"
>
<send>
if (GetLineInfo(GetLinesInBufferCount(), 1) == sAsciiMapString) then
EnableTrigger("AsciiMapLine", true)
EnableTrigger("AsciiMapPre", false)
end
</send>
</trigger>
<trigger
enabled="n"
keep_evaluating="y"
match="*"
regexp="n"
omit_from_output="n"
sequence="2"
script="HandleAsciiMapRedirection"
name="AsciiMapLine"
group="module_ascii"
>
</trigger>
<!-- Outgoing tells, stops triggering anyting else by accident -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> |\] )?You (?:[A-z]+ )?(?>tell |exclaim to |ask ).+?: "
regexp="y"
sequence="1"
script="HandleCommsMessage"
name="CommLog_Tells_Out"
group="module_comms"
>
</trigger>
<!-- Incoming tells, stops triggering anyting else by accident -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?:(?!You )[A-Za-z](?:\w+\b\W*?){1,9}) (?>tells|exclaims to|asks)(?>.+?you): "
regexp="y"
sequence="1"
script="HandleCommsMessage"
name="CommLog_Tells_In"
group="module_comms"
>
</trigger>
<!-- Group Says, pretty much anything in square brackets followed by some letters -->
<trigger
enabled="y"
keep_evaluating="y"
match="^(?:> )?\[(?!say|tell|soul|/| \])(?P<channel>[^\]]+)\] [A-Za-z]{3,}"
regexp="y"
sequence="3"
script="HandleCommsMessage"
name="CommLog_Group_Say"
group="module_comms"
>
</trigger>
<!-- Login informs -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?\[(?P<login>[A-Za-z]+) enters Discworld"
regexp="y"
sequence="3"
script="HandleLoginNotification"
>
</trigger>
<!-- You cre-tell -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
match="^You cre-tell:.+$"
regexp="y"
sequence="10"
name="QuowOutgoingCreTell"
script="QuowOutgoingCreTell"
>
</trigger>
<!-- You special-tell -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
match="^You special-tell:.+$"
regexp="y"
sequence="10"
name="QuowOutgoingSpecialTell"
script="QuowOutgoingSpecialTell"
>
</trigger>
<!-- You newbie-tell -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
match="^You newbie-tell:.+$"
regexp="y"
sequence="10"
name="QuowOutgoingNewbieTell"
script="QuowOutgoingNewbieTell"
>
</trigger>
<!-- Combat monitor and score-brief -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?Hp: (\d+) ?\((\d+)\) +(?:Gp\: (\d+) ?\((\d+)\)) +(?:Xp\: (\d+))(?: Burden: (\d+)\%)?$"
regexp="y"
sequence="4"
script="QuowHandleScoreBrief"
group="module_vitals"
>
</trigger>
<!-- You have joined a group -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?\[(?P<groupname>[^\]]+)\] You have joined the group\.$"
regexp="y"
omit_from_output="n"
sequence="9"
script="HandleGroupJoinMe"
name="GroupJoinYou"
group="module_shields"
>
</trigger>
<!-- You have left a group -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?\[(?P<groupname>[^\]]+)\] You have left the group\.$"
regexp="y"
omit_from_output="n"
sequence="9"
script="HandleGroupLeaveMe"
name="GroupLeaveYou"
group="module_shields"
>
</trigger>
<!-- Another player has joined your group -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?\[(?P<groupname>[^\]]+)\] (?P<player>[A-Za-z]+) has joined the group\.$"
regexp="y"
omit_from_output="n"
sequence="10"
script="HandleGroupJoinOther"
name="GroupJoinPlayer"
group="module_shields"
>
</trigger>
<!-- Another player has left your group -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?\[(?P<groupname>[^\]]+)\] (?P<player>[A-Za-z]+) has left the group\.$"
regexp="y"
omit_from_output="n"
sequence="10"
script="HandleGroupLeaveOther"
name="GroupLeavePlayer"
group="module_shields"
>
</trigger>
<!-- Group Status Brief for YOU (grab your name too) -->
<trigger
enabled="y"
keep_evaluating="y"
match="^(?:> )?(?P<player>[A-Za-z]+); Hp: \d+/\d+ Gp: \d+/\d+\.$"
ignore_case="y"
regexp="y"
sequence="10"
script="HandleGroupStatusMe"
name="GroupStatusMe"
group="module_shields"
>
</trigger>
<!-- Group Status for other players -->
<trigger
enabled="y"
keep_evaluating="y"
match="^(?:> )?(?: )?(?!(\[|>))(?P<player>[A-Za-z]+) is (?P<hp>unhurt|almost unhurt|scratched|slightly hurt|slightly injured|injured|slightly wounded|wounded|badly wounded|heavily wounded|seriously wounded|critically wounded|near death) and (?P<gp>refreshed|clear of mind|concentrated|slightly confused|confused|slightly fatigued|fatigued|very fatigued|highly fatigued|severely fatigued|near unconscious)\."
regexp="y"
sequence="11"
script="HandleGroupStatusOther"
name="GroupStatusOther"
group="module_shields"
>
</trigger>
<!-- Group Status for DEAD other players -->
<trigger
enabled="y"
keep_evaluating="y"
match="^(?:> )?(?: )?(?!(\[|>))(?P<player>[A-Za-z]+) is (?P<hp>perfectly healthy, for a ghost)(?P<gp>)\."
regexp="y"
sequence="11"
script="HandleGroupStatusOther"
name="GroupDeadOther"
group="module_shields"
>
</trigger>
<!-- Start of Arcane line gathering for YOU -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?Arcane protection status:$"
regexp="y"
omit_from_output="n"
sequence="11"
script="HandleArcaneTriggerMe"
name="ArcaneTriggerStartYou"
group="module_shields"
>
</trigger>
<!-- CCC Type 1 for YOU -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* Your skin (?>has been|has|is) (?>hardened to a rock-like form|hardened with numerous layers of a mineral-like substance|hardened with a chalk-like substance|covered with several layers of a chalk-like substance|covered with a thin layer of chalk|covered with a thick metal net|metal bands running all over it, forming a kind of net|covered with a thin metal net|covered with a thin, net-like metal coating|solidified into a rubberous form|made elastic with numerous layers of a rubber-like substance|treated with a latex-like substance|covered with several layers of a latex-like substance|covered with a thin layer of latex), although "
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNA_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* Tiny threads of metal run criss-cross all over your skin, although "
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield1_YNA_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?Your? (?>feel your skin become (?>rock hard|elastic as rubber)|skin (?>feels (?>even harder now|much more elastic now)|is now as (?>hard|elastic|thickly covered) as it can get))\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield1_YNU_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The metallic network on your skin feels a fair bit stronger now\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield2_YNU_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?Your skin feels itchy; large pieces flake off as you scratch it\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield1_YND_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?With a brief flash of magic, your (?>metallic|stony|elastic) skin falls away\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield2_YND_CCC"
group="module_shields"
>
</trigger>
<!-- TPA for YOU -->
<trigger
enabled="y"
keep_evaluating="y"
match="^ \* You are surrounded by a (?P<colour>|dull red |bright red |wobbling orange |flickering yellow )magical impact shield\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNA_TPA"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?With a noise that sounds like &quot;Plink!&quot;, everything around you flashes (?>yellow|red) for a moment\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNU_TPA"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?There is a sudden white flash\. Your magical shield has broken\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YND_TPA"
group="module_shields"
>
</trigger>
<!-- Bugs for YOU -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* You are surrounded by a (?>handful|cloud|small swarm|large swarm|vast swarm|plague) of"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNA_KII"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?>Buzzing drowsily, t|Buzzing loudly, t|Buzzing threateningly, t|Clicking and buzzing, t|Whirring gently, t|Rather clumsily, t|With a rasping noise, t|With a high-pitched whining noise, t|With a low, menacing buzzing, t|With a buzzing sound so loud and meaty it's almost like a dog growling, t|T)he (?>handful|cloud|small swarm|large swarm|vast swarm|plague) of (?>lacewings|stick insects|mayflies|praying mantids|butterflies|ladybirds|dragonflies|damselflies|moths|grasshoppers|winged termites|sandflies|mosquitoes|gnats|crickets|flying ants|locusts|horseflies|cicadas|bees|wasps|hornets|elephant beetles|assassin bugs) (?>flutters into a loosely-formed orbit around |forms a chaotic web of small white bodies around|starts to hover near |begins to circle |begins to circle around |begins to orbit |begins to cluster around |begins to buzz erratically around |begins to buzz around |flutters into a chaotic formation around )you"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNU_KII"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The (?>lacewings|stick insects|mayflies|praying mantids|butterflies|ladybirds|dragonflies|damselflies|moths|grasshoppers|winged termites|sandflies|mosquitoes|gnats|crickets|flying ants|locusts|horseflies|cicadas|bees|wasps|hornets|elephant beetles|assassin bugs) surrounding you scatter in different directions and fly off\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield1_YND_KII"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The last of the injured (?>lacewings|stick insects|mayflies|praying mantids|butterflies|ladybirds|dragonflies|damselflies|moths|grasshoppers|winged termites|sandflies|mosquitoes|gnats|crickets|flying ants|locusts|horseflies|cicadas|bees|wasps|hornets|elephant beetles|assassin bugs) surrounding you crash to the ground\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield2_YND_KII"
group="module_shields"
>
</trigger>
<!-- Major for YOU -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* You are (?>(?>barely |really |perfectly )?protected|shielded) by the (?>power |protective armour )of (?>Pishe|Gufnork|Gapp|Sandelfon|Fish|Hat|Sek)\. You will be protected for "
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNA__MS"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?You are protected by the power of (?>Pishe|Gufnork|Gapp|Sandelfon|Fish|Hat|Sek)\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNU__MS"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?Your divine protection expires\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YND__MS"
group="module_shields"
>
</trigger>
<!-- EFF for YOU -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* (?P<effitem>(?:\w+\b\W*?){1,6}) is floating around you\:$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNA_EFF"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<effitem>(?:\w+\b\W*?){1,6}) begins to float around you\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield_YNU_EFF"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?In blocking the attack (?P<effitem>(?:\w+\b\W*?){1,6}) floating around you is knocked out of orbit\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield1_YND_EFF"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?You realise that (?P<effitem>(?:\w+\b\W*?){1,6}) is no longer floating around you\.$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield2_YND_EFF"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<effitem>(?:\w+\b\W*?){1,6}) floating around you breaks!$"
regexp="y"
sequence="12"
script="HandleShieldData"
name="ArcaneShield3_YND_EFF"
group="module_shields"
>
</trigger>
<!-- No shields at all for YOU -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?You do not have any arcane protection\.$"
regexp="y"
sequence="11"
script="HandleArcaneTriggerOther"
name="ArcaneShieldNothingYou"
group="module_shields"
>
</trigger>
<!-- Start of Arcane line gathering for OTHER players -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?Arcane protection for (?P<player>[A-Za-z]+):-$"
regexp="y"
omit_from_output="n"
sequence="13"
script="HandleArcaneTriggerOther"
name="ArcaneTriggerStart"
group="module_shields"
>
</trigger>
<!-- No shields at all for OTHER players -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<player>(?:\w+\b\W*?){1,8}) has no arcane protection\.$"
regexp="y"
sequence="13"
script="HandleArcaneTriggerOther"
name="ArcaneShieldNothing"
group="module_shields"
>
</trigger>
<!-- CCC Type 1 for OTHER players -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* (?>His|Her|Its) skin (?>has been|has|is) (?>hardened to a rock-like form|hardened with numerous layers of a mineral-like substance|hardened with a chalk-like substance|covered with several layers of a chalk-like substance|covered with a thin layer of chalk|covered with a thick metal net|metal bands running all over it, forming a kind of net|covered with a thin metal net|covered with a thin, net-like metal coating|solidified into a rubberous form|made elastic with numerous layers of a rubber-like substance|treated with a latex-like substance|covered with several layers of a latex-like substance|covered with a thin layer of latex), although "
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONA_CCC"
group="module_shields"
>
</trigger>
<!-- CCC Type 2 for OTHER players -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* Tiny threads of metal run criss-cross all over (?>her|his|its) skin, although "
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield2_ONA_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<player>(?:\w+\b\W*?){1,8})'s skin becomes (?>elastic as rubber|rock hard)\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield1_ONU_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The metal powder fuses together into metal bands on (?P<player>(?:\w+\b\W*?){1,8})'s skin\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield2_ONU_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<player>(?:\w+\b\W*?){1,8})'s skin is now as (?>elastic|thickly covered|hard) as it can get\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield3_ONU_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<player>(?:\w+\b\W*?){1,8}) scratches (?>himself|herself|itself), and large pieces of skin flake off\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield1_OND_CCC"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?There is a brief flash of magic, and something falls away from (?P<player>(?:\w+\b\W*?){1,8})'s skin\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield2_OND_CCC"
group="module_shields"
>
</trigger>
<!-- TPA for OTHER players -->
<trigger
enabled="y"
keep_evaluating="y"
match="^ \* (?>She|He|It) is surrounded by a (?P<colour>|dull red |bright red |wobbling orange |flickering yellow )magical impact shield\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONA_TPA"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?With a noise that sounds like &quot;Plink!&quot;, the air around (?P<player>(?:\w+\b\W*?){1,8}) flashes (?>yellow|red) for a moment\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONU_TPA"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?There is a sudden white flash around (?P<player>(?!a passing wizard)(?:\w+\b\W*?){1,8})\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_OND_TPA"
group="module_shields"
>
</trigger>
<!-- Bugs for OTHER players -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* (?>She|He|It) is surrounded by a (?>handful|cloud|small swarm|large swarm|vast swarm|plague) of "
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONA_KII"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?>Buzzing drowsily, t|Buzzing loudly, t|Buzzing threateningly, t|Clicking and buzzing, t|Whirring gently, t|Rather clumsily, t|With a rasping noise, t|With a high-pitched whining noise, t|With a low, menacing buzzing, t|With a buzzing sound so loud and meaty it's almost like a dog growling, t|T)he (?>handful|cloud|small swarm|large swarm|vast swarm|plague) of (?>lacewings|stick insects|mayflies|praying mantids|butterflies|ladybirds|dragonflies|damselflies|moths|grasshoppers|winged termites|sandflies|mosquitoes|gnats|crickets|flying ants|locusts|horseflies|cicadas|bees|wasps|hornets|elephant beetles|assassin bugs) (?>flutters into a loosely-formed orbit around |forms a chaotic web of small white bodies around|starts to hover near |begins to circle |begins to circle around |begins to orbit |begins to cluster around |begins to buzz erratically around |begins to buzz around |flutters into a chaotic formation around )(?P<player>(?:\w+\b\W*?){1,8})(?:| happily| slowly|, chirping gently|, buzzing hungrily)\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONU_KII"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The (?>lacewings|stick insects|mayflies|praying mantids|butterflies|ladybirds|dragonflies|damselflies|moths|grasshoppers|winged termites|sandflies|mosquitoes|gnats|crickets|flying ants|locusts|horseflies|cicadas|bees|wasps|hornets|elephant beetles|assassin bugs) surrounding (?P<player>(?:\w+\b\W*?){1,8}) scatter in different directions and fly off\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield1_OND_KII"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The last of the injured (?>lacewings|stick insects|mayflies|praying mantids|butterflies|ladybirds|dragonflies|damselflies|moths|grasshoppers|winged termites|sandflies|mosquitoes|gnats|crickets|flying ants|locusts|horseflies|cicadas|bees|wasps|hornets|elephant beetles|assassin bugs) surrounding (?P<player>(?:\w+\b\W*?){1,8}) crash to the ground\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield2_OND_KII"
group="module_shields"
>
</trigger>
<!-- Major for OTHER players -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* (?>She|He|It) is (?>really )?protected by the power of (?>Pishe|Gufnork|Gapp|Sandelfon|Fish|Hat|Sek)"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONA__MS"
group="module_shields"
>
</trigger>
<!-- EFF for OTHER players -->
<trigger
enabled="y"
keep_evaluating="n"
match="^ \* (?P<effitem>(?:\w+\b\W*?){1,6}) is floating around (?>him|her|it)\:$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONA_EFF"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<effitem>(?:\w+\b\W*?){1,6}) begins to float around (?P<player>(?:\w+\b\W*?){1,8})\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield_ONU_EFF"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?In blocking the attack (?P<effitem>(?:\w+\b\W*?){1,6}) floating around (?P<player>(?:\w+\b\W*?){1,8}) is knocked out of orbit\.$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield1_OND_EFF"
group="module_shields"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?P<effitem>(?:\w+\b\W*?){1,6}) floating around (?P<player>(?:\w+\b\W*?){1,8}) breaks!$"
regexp="y"
sequence="14"
script="HandleShieldData"
name="ArcaneShield2_OND_EFF"
group="module_shields"
>
</trigger>
<!-- Kill - outgoing -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="deepskyblue"
match="^(?:> )?You kill (?P<vic>(?:\w+\b\W*?){1,8})\.$"
regexp="y"
sequence="15"
script="StatsKillStatOutgoing"
name="QuowKillStatOut1"
>
</trigger>
<!-- Kills - third party -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="darkcyan"
match="^(?:> )?(?P<att>(?!You )(?:\w+\b\W*?){1,8}) deals the death blow to (?P<vic>(?!you |you,)(?:\w+\b\W*?){1,8})\.$"
regexp="y"
sequence="16"
script="StatsKillStatThird"
name="StatsKillStatThird1"
>
</trigger>
<!-- Kills - incoming -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="red"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) deals the death blow to you\.$"
regexp="y"
sequence="17"
script="StatsKillStatIncoming"
name="QuowKillStatInc1"
>
</trigger>
<!-- Follow another player in a recognised direction -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?You (?:follow|pursue) [a-zA-Z](?:\w+\b\W*?){1,8} (north|northeast|east|southeast|south|southwest|west|northwest|left|right|forward|backward|up|down)\.$"
regexp="y"
script="FollowHandler"
name="FollowHandle"
sequence="10"
group="module_minimap"
>
</trigger>
<!-- Movement is simply impossible in this direction -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?>What\?|That doesn't work\.|Try something else\.)$"
regexp="y"
script="MovementFailure"
name="MoveFail"
sequence="10"
group="module_minimap"
>
</trigger>
<!-- Command queue cleared -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?>Removed queue\.|Thanks for playing\. See you next time\.)$"
regexp="y"
script="MovementQueueClear"
name="MoveClear"
sequence="10"
group="module_minimap"
>
</trigger>
<!-- Movement SHOULD be possible, but was intercepted by something -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?>The door swings shut in your face\.|The (?>north |northeast |east |southeast |south |southwest |west |northwest |warehouse )?(?>door|gate) is locked\.|(?>Free Sitting Birds|Nella|Jonas|Master Brimstone|Will|Thella|Nostos|Philip LeGrande) intercepts you\.|Try as you might, the sheep block any further progress south\.|(?:\w+\b\W*?){1,4} blocks the exit and prevents you from leaving (?>northeast|southeast|southwest|northwest|north|east|south|west)\.|That exit is creator-only for the moment\.|You do your best to get through the turnstiles, but the crowds are simply too thick and you make no headway\. Better come back later, maybe they'll be more accessible then\.|A magic force prevents you from going that way\.|The bridge troll bars your way\.|The bridge troll is blocking the entire road very effectively, and you just can't sneak past him\.|The (?>north |northeast |east |southeast |south |southwest |west |northwest )?door slams shut in your face\.|Some unseen force grabs hold of you and pushes you back\.|Some sort of invisible field stops you from going that way at this point in time\.|A wooden barrier prevents your progress in this direction\.|A giant grabs you as you try to leave!|Four bandits leap out from hiding!|The (ceremonial)? (guard|sentry) blocks your way.|One of the guard thieves stops you from entering\.|A terrible sense of foreboding comes over you as you try to go .+\.|You can't go that way - a vine trellis is totally blocking the path\.)$"
regexp="y"
script="MovementBlockage"
name="MoveBlock"
sequence="20"
group="module_minimap"
>
</trigger>
<!-- Brief-look library warning! -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The Library \[rt,lt,s\]\.$"
regexp="y"
script="HandleLibraryBriefLook"
name="HandleLibraryBriefLook"
sequence="10"
>
</trigger>
<!-- Watch exits until we know we are getting GMCP data for user reconnect warnings -->
<trigger
enabled="y"
keep_evaluating="y"
match="^There (?>are|is) (?:\w+\b\W*?){1,2} obvious exit"
omit_from_output="n"
sequence="15"
script="QuowConfirmExitsSeen"
regexp="y"
name="RoomExitsSeenLong"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="y"
match="^[a-zA-Z].+ \[.+\]\.$"
omit_from_output="n"
sequence="15"
script="QuowConfirmExitsSeen"
regexp="y"
name="RoomExitsSeenShort"
>
</trigger>
<!-- Distortion seen in the Library -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?There is a strange distortion in space and time (.+) you!$"
regexp="y"
script="UULibraryDistortion"
sequence="15"
group="module_minimap"
>
</trigger>
<!-- New distortion has formed in the room, caution! -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?(?>You notice an odd rippling in the air\.|The awful sound of nails being dragged down a blackboard fills the area briefly\.|A distortion in time and space is forming!)$"
regexp="y"
script="HandleDistortionFormed"
name="NewDistortion"
sequence="15"
>
</trigger>
<!-- New distortion has formed in the room, caution! -->
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?The area seems more mundane than before\.$"
regexp="y"
script="HandleDistortionVanish"
name="DistortionVanish"
sequence="15"
>
</trigger>
<!-- Escaped orbs in the room/library -->
<trigger
enabled="y"
keep_evaluating="n"
match="(?>a|A) (tiny speck|small point|moderately-sized ball|large orb|substantial sphere) of energy is tracing a (?:.+?) pattern in the air"
regexp="y"
script="HandleLibraryOrb"
name="UULibraryOrbs"
sequence="20"
group="module_minimap"
>
</trigger>
<!-- Hide Speed-Walk Alias Changes as spam -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="y"
match="^(?:> )?Changed alias &quot;MooMooQuowsRun&quot; from &quot;"
regexp="y"
name="QuowHideSpeedwalkChange"
sequence="20"
group="module_minimap"
>
</trigger>
<!-- Only used when recording shop data for database creation, off by default -->
<trigger
enabled="n"
keep_evaluating="n"
match="^ ([A-Z]{1,2}): (.+) for (.+?)( \((.+?) left\)){0,1}\.$"
regexp="y"
script="ShopInventory"
name="ShopInventory"
sequence="20"
>
</trigger>
<!-- Backstabbings - outgoing -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You (?>skilfully |silently )?sneak around (?:\w+\b\W*?){1,8} without being spotted and manage to catch (?>him|her|it) by surprise\.$"
regexp="y"
script="StatsSpecialSuccessNoHitOutgoing"
name="QuowSpecialBackstabSuccessOut"
sequence="30"
group="module_stats"
>
</trigger>
<!-- Ambushes - outgoing -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You leap out on (?:\w+\b\W*?){1,8}, catching (?>him|her|it) by surprise\.$"
regexp="y"
script="StatsSpecialSuccessNoHitOutgoing"
name="QuowSpecialAmbushSuccessOut"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You are about to leap out on (?:\w+\b\W*?){1,8}, but (?>he|she|it) spots you!$"
regexp="y"
script="StatsSpecialFailNoHitOutgoing"
name="QuowSpecialAmbushFailOut"
sequence="30"
group="module_stats"
>
</trigger>
<!-- Absconds - outgoing -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You quickly slip behind (?:\w+\b\W*?){1,8} and, before (?>he|she|it) can react, you head towards the (?:.+) exit\.$"
regexp="y"
script="StatsSpecialSuccessNoHitOutgoing"
name="QuowSpecialAbscondSuccessOut"
sequence="30"
group="module_stats"
>
</trigger>
<!-- Backstabs Incoming -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) attacks you from behind\. You recall (?>him|her|it) standing right in front of you just a second ago\.$"
regexp="y"
script="StatsSpecialSuccessNoHitIncoming"
name="QuowSpecialBackstabSuccessInc"
sequence="31"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You suddenly (?>sense a presence|hear a noise) behind you and turn around to (?>see|find) (?:\w+\b\W*?){1,8} preparing to backstab you\. You (?>decide to teach (?>him|her|it) a lesson|take the opportunity to launch a pre-emptive attack)\.$"
regexp="y"
script="StatsSpecialFailNoHitIncoming"
name="QuowSpecialBackstabFailInc"
sequence="31"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You notice (?:\w+\b\W*?){1,8} falling over (?>his|her|its) feet while trying to sneak round you and decide to teach (?>him|her|it) a lesson\.$"
regexp="y"
script="StatsSpecialFailNoHitIncoming"
name="QuowSpecialBackstabFail2Inc"
sequence="31"
group="module_stats"
>
</trigger>
<!-- Backstabs - third party -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) manages to get around (?:(?!you )(?:\w+\b\W*?){1,8})'s defences and launches a vicious attack\.$"
regexp="y"
script="StatsSpecialSuccessNoHitThird"
name="QuowSpecialBackstabSuccessThird"
sequence="32"
group="module_stats"
>
</trigger>
<!-- Ambushes - third party -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) expertly executes an ambush attack on (?:(?!you )(?:\w+\b\W*?){1,8})\.$"
regexp="y"
script="StatsSpecialSuccessNoHitThird"
name="QuowSpecialAmbushSuccessThird"
sequence="32"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) notices (?:(?!you )(?:\w+\b\W*?){1,8}) trying to ambush (?>him|her|it) and turns around to teach (?>him|her|it) a lesson\.$"
regexp="y"
script="StatsSpecialFailNoHitThird"
name="QuowSpecialAmbushFailThird"
sequence="32"
group="module_stats"
>
</trigger>
<!-- Absconds - third party -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) suddenly ducks behind (?:(?!you )(?:\w+\b\W*?){1,8}) and heads towards the (?:.+) exit\.$"
regexp="y"
script="StatsSpecialSuccessNoHitThird"
name="QuowSpecialAbscondSuccessThird"
sequence="32"
group="module_stats"
>
</trigger>
<!-- Incoming feints -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) moves as though about to launch a powerful attack and you prepare to defend yourself\. Too late, you realise that it is a feint and you are left (?>momentarily )?off balance(?> and exposed)?\.$"
regexp="y"
script="StatsSpecialSuccessIncoming"
name="QuowFeintSuccessIncoming1"
sequence="31"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) moves as though about to launch a powerful attack but you realise it is a feint and do not react\.$"
regexp="y"
script="StatsSpecialFailIncoming"
name="QuowFeintFailIncoming1"
sequence="31"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You move as though about to launch a powerful attack on (?:\w+\b\W*?){1,8}\. (?>He|She|It) sees through your feint and doesn't react\.$"
regexp="y"
script="StatsSpecialFailOutgoing"
name="QuowFeintFailOutgoing1"
sequence="31"
group="module_stats"
>
</trigger>
<!-- Dodge throwing weapons -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?You(?P<level> barely| quickly| swiftly)(?P<type> dodge) out of the path of the (?:(?:\w+\b\W*?){1,8})\.$"
regexp="y"
script="StatsMeleeFailIncoming"
name="QuowThrowingFailInc1"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8})(?P<level> barely| quickly| swiftly)(?P<type> dodges) out of the (?:(?:\w+\b\W*?){1,8}) path\.$"
regexp="y"
script="StatsMeleeFailThird"
name="QuowThrowingFailThird1"
sequence="31"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) (?P<shielding>floating around )you(?> barely| quickly| swiftly) swoops in and blocks (?:\w+\b\W*?){1,8}\.$"
regexp="y"
script="StatsMeleeFailIncoming"
name="QuowThrowingFailInc2"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) (?P<shielding>floating around )(?:(?!you )(?:\w+\b\W*?){1,8})(?> barely| quickly| swiftly) swoops in and blocks (?:\w+\b\W*?){1,8}\.$"
regexp="y"
script="StatsMeleeFailThird"
name="QuowThrowingFailThird2"
sequence="31"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) bounces off your (?P<shielding>magical shielding)\.$"
regexp="y"
script="StatsMeleeFailIncoming"
name="QuowThrowingFailInc3"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) bounces off (?:(?!you )(?:\w+\b\W*?){1,8}) (?P<shielding>magical shielding)\.$"
regexp="y"
script="StatsMeleeFailThird"
name="QuowThrowingFailThird3"
sequence="31"
group="module_stats"
>
</trigger>
<!-- Knockout Dodging -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#1E90FF"
match="^(?:> )?(?:\w+\b\W*?){1,8} aims a knock-out blow at the back of your head, but you(?P<type> dodge) it in time\.$"
regexp="y"
script="StatsMeleeFailIncoming"
name="QuowMiscFailInc1"
sequence="30"
group="module_stats"
>
</trigger>
<!-- You FAIL to prepare a special -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="magenta"
match="^(?:> )?You attempt to (?>bash |beat |bob |chop |feint |hack |kick |pierce |punch |riposte |shove |slash |smash |stab |trip |crush |behead |impale |flick |launch a wildswing attack )(?:.+?) but (?>cannot find an opportunity|you move too slowly and lose the initiative)\.$"
regexp="y"
script="StatsSpecialPrepareFail"
name="QuowMeleeSpecialFail1"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="magenta"
match="^(?:> )?You lose the moment\.$"
regexp="y"
script="StatsSpecialPrepareFail"
name="QuowMeleeSpecialFail2"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="magenta"
match="^(?:> )?You try to (?>trip |shove )(?:\w+\b\W*?){1,8} but fail and stumble(?:| slightly)\.$"
regexp="y"
script="StatsSpecialPrepareFail"
name="QuowMeleeSpecialFail3"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="magenta"
match="^(?:> )?You attempt to prepare a special attack but (?:\w+\b\W*?){1,8} feels too unwieldy and you lose the initiative\.$"
regexp="y"
script="StatsSpecialPrepareFail"
name="QuowMeleeSpecialFail4"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="magenta"
match="^(?:> )?You attempt to slip behind (?:\w+\b\W*?){1,8}, but (?>he|she|it) spots you and you fail to get away\.$"
regexp="y"
script="StatsSpecialPrepareFail"
name="QuowMeleeSpecialFail5"
sequence="30"
group="module_stats"
>
</trigger>
<!-- You prepare a special -->
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="darkgreen"
match="^(?:> )?You prepare to (?>bash |beat |bob |chop |feint |hack |kick |pierce |punch |riposte |shove |slash |smash |stab |trip |crush |behead |impale |flick |launch a wildswing attack ).+\.$"
regexp="y"
script="StatsSpecialPrepareSuccess"
name="QuowMeleeSpecialPrepare1"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="darkgreen"
match="^(?:> )?You begin watching for an opportunity to flick (?:.+?) at (?:\w+\b\W*?){1,8}\.$"
regexp="y"
script="StatsSpecialPrepareSuccess"
name="QuowMeleeSpecialPrepare2"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="darkgreen"
match="^(?:> )?You situate yourself for a graceful and quiet exit\.$"
regexp="y"
script="StatsSpecialPrepareSuccess"
name="QuowMeleeSpecialPrepare3"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="darkgreen"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) reaches for you and stumbles\.$"
regexp="y"
script="StatsSpecialFailIncoming"
name="QuowSpecialFailIncCustom1"
sequence="30"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#3C4420"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) reaches for (?:(?!you )(?:\w+\b\W*?){1,8}) and stumbles\.$"
regexp="y"
script=""
name="StatsSpecialFailThirdCustom1"
sequence="31"
group="module_stats"
>
</trigger>
<trigger
enabled="y"
keep_evaluating="n"
omit_from_output="n"
custom_colour="17"
other_text_colour="#3C4420"
match="^(?:> )?(?:(?!You )(?:\w+\b\W*?){1,8}) moves towards (?:(?!you )(?:\w+\b\W*?){1,8}) as though about to launch a powerful attack\. (?:(?!You )(?:\w+\b\W*?){1,8}) does not react, seeing that it was a feint\.$"
regexp="y"
script=""
name="StatsSpecialFailThirdCustom2"
sequence="31"
group="module_stats"
>
</trigger>
<!-- Combat Colour Trigger Filter -->
<trigger
enabled="n"
keep_evaluating="y"
omit_from_output="n"
match="*"
regexp="n"
name="QuowStatOptimizer"
sequence="40"
send_to="12"
>
<send>
if (GetStyleInfo(GetLinesInBufferCount(), 2, 14) ~= 65535) then
StopEvaluatingTriggers(false)
end
</send>
</trigger>
</triggers>
<!-- Aliases -->
<aliases>
<alias
match="hidecombatspam"
enabled="y"
ignore_case="y"
sequence="30"
script="ToggleCombatSpam"
>
</alias>
<alias
match="help minimap"
enabled="y"
ignore_case="y"
sequence="30"
script="DisplayHelpFile"
>
</alias>
<alias
match="minimap"
enabled="y"
ignore_case="y"
sequence="30"
script="MinimapCommandHandler"
>
</alias>
<alias
match="mm"
enabled="n"
ignore_case="y"
sequence="30"
name="QuowShortMM"
script="MinimapCommandHandler"
>
</alias>
<alias
match="minimap *"
enabled="y"
ignore_case="y"
sequence="30"
script="QuowMapCommand"
>
</alias>
</aliases>
<!-- Timers -->
<timers>
<timer
script="UpdateXPGraph"
enabled="y"
minute="1"
name="timer_xpgraph"
>
</timer>
<timer
script="UpdateDiscDate"
enabled="y"
second="20.00"
name="timer_discdate"
>
</timer>
<timer
script="UpdateGPGeneration"
enabled="y"
second="2.00"
name="timer_gpregen"
>
</timer>
</timers>
</muclient>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment