BLIND MONITOR FOR JMC Tested on JMC version 3.26 (c) Rashnak 2003-01-17 This library started as a monitoring tool to help notice when targets are about to lose blind effect, by counting seconds from when you blind them. It has evolved from that somewhat, to include a keyword shortcut system for your targets. Here is the alias to set shortcuts: #alias bb {#script blindShortcutSet "%1", "%2"} Example: >bb o orc >bb t troll >bb w wolf The data structures in this script are implemented with static arrays, limit for shortcuts is at 100. Applying target shortcuts when blinding: #alias b {#script blindShortcut "%1", "%2"} >b o 5 --> cast 'blind' 5.orc >b t --> cast 'blind' troll >b w 2 --> cast 'blind' 2.wolf The need for this shortcut system arised from the fact that it was impossible to keep track of blind targets without channeling all blind attempts through one common JMC alias (in this case, "b"). Here is the alias to see all blind targets: #alias blinds {#script blindTable} Here is what a possible output looks like: >blinds 82 An orkish warrior (4.warrior) 78 An orkish warrior (3.warrior) 75 An orkish warrior (1.warrior) 68 An orkish warrior (2.warrior) 57 A great warg (2.warg) 55 A great warg (warg) 44 A lurg leader (lurg) -20 A huge stone troll (troll) Duration of blindness on MUME at the moment is 90 seconds, which is configurable in variable "blindDuration". The timer displayed with blind monitor, using the command "blinds", counts down from 90 to 0. At 0 the blind effect is gone, but the target is not removed from the blind list until counter runs to -30. Notice that the library does NOT keep track of targets dying or otherwise changing room order, so in the above example if you kill 1.warg first, the entry for 2.warg will stay as it is, although that warg has now become 1.warg. Another flaw in the system is that the target keyword tracking only works if you are the only one casting blinds. If there is another blinder, the library will not be able to tell the keywords in parentheses correctly. You may get results like this: 44 A lurg leader (2.warg) If this happens, you need to use the "BlindClean" command to reset the keyword tracking array: #alias BlindClean {#script blindAttemptClean} Similarly to the shortcut array, the limit for blinded targets at one time is 100. Here are some necessary JMC macros: #action {/^Aye! You cannot concentrate any more.../} {#script blindAttemptRoll} #action {/^Nothing seems to happen.$/} {#script blindAttemptRoll} #action {/^Your victim is already blind.$/} {#script blindAttemptRoll} #action {/^Nobody here by that name.$/} {#script blindAttemptRoll} #action {/^Nah... You feel too relaxed to do that..$/} {#script blindAttemptRoll} #action {/^In your dreams, or what?$/} {#script blindAttemptRoll} There are other similar cases where you have started a blind spell but it does not go through correctly. You can follow the same syntax to work around them, if you mess up your script too much. I have got along with just these. You may have to turn #multiaction ON if you have other actions that trigger on same patterns. To use other aliases in addition to "b", building them like this will make them compatible with the blind monitor: #alias bli {#script blindAttemptAdd "%1"; cast 'blind' %1} Example: >bli takhr The following VBScript code goes into "settings\commonlib.scr". '******************************************************* ' BLIND MONITOR: VBSCRIPT CODE STARTS HERE ' First some settings '******************************************************* ' Duration of blind spell effect in seconds dim blindDuration blindDuration = 90 ' Internal purge limit. Blinded opponents ' get purged from the blind table at this limit. dim blindLifeTime blindPurgeLimit = -30 ' Toggle target keyword tracking ON/OFF (1/0) dim blindTargetKeywordTracking blindTargetKeywordTracking = 1 ' The blind table dim arrayBlindData(100, 3) ' the second index of arrayBlinddata can have these values: dim blName ' Index 0 NAME dim blActivated ' Index 1 ACTIVATED dim blKeyword ' Index 2 KEYWORD blName = 0 ' Name of blinded opponent blActivated = 1 ' Time when it was blinded blKeyword = 2 ' MUME keyword for the opponent (bear, troll, 3.orc...) ' This is the event handler for all lines coming from MUME. ' Look the documentation of "Communication Library" for further ' information about this event handler. Sub Jmc_Incoming (line) dim match match = false if (not match) then match = HerbalIncoming(line) end if if (not match) then match = ComIncoming(line) end if if (not match) then match = BlindIncoming(line) end if End sub ' This function tests the input line for any blind-related data. ' It replaces this action: ' Returns True if there was a match. Function BlindIncoming(line) dim match, regEx match = false Set regEx = New RegExp regEx.pattern = "^(.*)\sseems\sto\sbe\sblinded!$" if (regEx.test(line)) then ' MATCH: something is blinded! match = true Set m_matches = regEx.Execute(line) Set m_match = m_matches(0) blindSet m_match.SubMatches(0) end if BlindIncoming = match End Function '******************************************************* ' BLIND MONITOR: blindIdByName (blindName) ' Returns the index number for blindName ' if not found, return an unused index available ' if none available, -1 '****************************************************** Function blindIdByName (blindName) dim blindId blindId = -1 dim freeId freeId = -1 dim i i = 0 do while (i < 100) ' Loop through entire blind table ' Calculate the remaining duration dim blindDurationLeft blindDurationLeft = blindDuration - DateDiff("s", arrayBlindData(i, blActivated), Time) if (blindDurationLeft < blindPurgeLimit) then ' Clear this index arrayBlindData(i, blName) = "" end if if (blindDurationLeft > blindDuration) then ' BUGGED INDEX: Clear it arrayBlindData(i, blName) = "" end if if (arrayBlindData(i, blName) = blindName) then ' This index matches our search if (blindDurationLeft > 0) then ' This index is still blind, leave it as it is. else ' Return this index. blindId = i exit do end if end if if (arrayBlindData(i, blName) = "") then ' Prepare to return this index as free index. freeId = i end if i = i + 1 loop if (blindId = -1) then blindId = freeId end if blindIdByName = blindId End Function '******************************************************* ' BLIND MONITOR: blindSet (blindName) ' Sets the status of the given opponent to blindStatus '****************************************************** Sub blindSet (blindName) dim blindId blindId = blindIdByName(blindName) dim blindKeyword blindKeyword = "" if (blindTargetKeywordTracking = 1) then blindKeyword = blindAttemptGet() end if if (blindId <> -1) then arrayBlindData(blindId, blName) = blindName arrayBlindData(blindId, blActivated) = Time arrayBlindData(blindId, blKeyword) = blindKeyword end if End Sub '******************************************************* ' BLIND MONITOR: blindTable ' Displays a table of all blinded opponents '****************************************************** Sub blindTable i = 0 jmc.ShowMe("") do while (i < 100) ' Loop through blind table ' Calculate the remaining duration dim blindDurationLeft blindDurationLeft = blindDuration - DateDiff("s", arrayBlindData(i, blActivated), Time) if (blindDurationLeft < blindPurgeLimit) then ' Clear this index arrayBlindData(i, blName) = "" end if if (blindDurationLeft > blindDuration) then ' BUGGED INDEX: Clear it arrayBlindData(i, blName) = "" end if if (arrayBlindData(i, blName) <> "") then ' This index has an entry ' Format output dim durationString durationString = blindDurationLeft do while (Len(durationString) < 6) durationString = " " & durationString loop dim outputLine outputLine = durationString & " " & arrayBlindData(i, blName) if (blindTargetKeywordTracking = 1) then outputLine = outputLine & " (" & arrayBlindData(i, blKeyword) & ")" end if jmc.ShowMe(outputLine) end if i = i + 1 loop End Sub ' The blind attempt table dim arrayBlindAttemptData(50) '******************************************************* ' BLIND MONITOR: blindAttemptAdd (blindKeyword) ' Adds a new target to blind attempt array '****************************************************** Sub blindAttemptAdd(blindKeyword) if (blindTargetKeywordTracking = 0) then exit sub end if dim i i = 49 do while (i > -1) if (arrayBlindAttemptData(i) = "") then arrayBlindAttemptData(i) = blindKeyword exit do end if i = i - 1 loop if (i = -1) then msgbox "ERROR: blindAttemptAdd(): arrayBlindAttemptData is full." end if End Sub '******************************************************* ' BLIND MONITOR: blindAttemptClean ' Cleans the blind attempt array '****************************************************** Sub blindAttemptClean do while (arrayBlindAttemptData(49) <> "") blindAttemptRoll loop End Sub '******************************************************* ' BLIND MONITOR: blindAttemptRoll ' Rolls the blind attempt array to right. '****************************************************** Sub blindAttemptRoll dim i i = 49 do while (i > 0) arrayBlindAttemptData(i) = arrayBlindAttemptData(i-1) i = i - 1 loop arrayBlindAttemptData(0) = "" End Sub '******************************************************* ' BLIND MONITOR: blindAttemptGet ' Returns the last attempt in the array '****************************************************** Function blindAttemptGet blindAttemptGet = arrayBlindAttemptData(49) blindAttemptRoll End Function ' The blind shortcut table dim arrayBlindShortcutData(100, 2) ' the second index of arrayBlindShortcutData can have these values: dim blCmdKeyword ' Index 0 KEYWORD dim blCmdTarget ' Index 1 TARGET blCmdKeyword = 0 ' Keyword for shortcut blCmdTarget = 1 ' Target keyword '******************************************************* ' BLIND MONITOR: blindShortcutIndex (blindKeyword) ' Returns the index number for blindKeyword ' if not found, return an unused index available ' if none available, -1 '****************************************************** Function blindShortcutIndex (blindKeyword, orFree) dim id id = -1 dim freeId freeId = -1 dim i i = 0 do while (i < 100) ' Loop through entire blind command table if (arrayBlindShortcutData(i, blCmdKeyword) = blindKeyword) then ' Return this index. id = i exit do end if if (arrayBlindShortcutData(i, blCmdKeyword) = "") then ' Prepare to return this index as free index. freeId = i end if i = i + 1 loop if (orFree = 1 and id = -1) then id = freeId end if blindShortcutIndex = id End Function '******************************************************* ' BLIND MONITOR: blindShortcutSet ' Sets a blind shortcut in the blind shortcut array '****************************************************** Sub blindShortcutSet (blindKeyword, blindTarget) dim id id = blindShortcutIndex(blindKeyword, 1) if (id <> -1) then arrayBlindShortcutData(id, blCmdKeyword) = blindKeyword arrayBlindShortcutData(id, blCmdTarget) = blindTarget else msgbox "ERROR: blindShortcutSet(): arrayBlindShortcutData is full." end if End Sub '******************************************************* ' BLIND MONITOR: blindShortcut ' Casts the spell using given keyword shortcut '****************************************************** Sub blindShortcut (blindKeyword, blindTargetNumber) dim id id = blindShortcutIndex(blindKeyword, 0) dim cmd cmd = "bli" if (blindKeyword <> "") then cmd = cmd & " " end if if (id <> -1) then if (blindTargetNumber <> "") then cmd = cmd & blindTargetNumber & "." end if cmd = cmd & arrayBlindShortcutData(id, blCmdTarget) else cmd = cmd & blindKeyword end if jmc.parse(cmd) End Sub