User:Ilde/MajorTimer
From Discworld MUD Wiki
<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE muclient> <!-- Original by Garrion --> <!-- Version 3.2 by Ilde, built upon version 2.1 --> <!-- MuClient version 4.40 --> <!-- This plugin keeps track of how much Major Shield you have. "help majortimer" will display a helpfile with available commands. It's fine to make your own version of this plugin or use parts of it. NOTE: Before using for the first time (that is, after installing, but before performing Major Shield), use the mtchar command to tell it what character you're logged in as, and use the mtset command to tell it your bonus. The syntax is "mtchar <name>" and "mtset <number>". Please note that this may not work correctly when using Minor Shield, or when mixing Major and Minor Shield. --> <muclient> <plugin name="MajorTimer" author="Ilde" id="f6685da86910795e76a1884c" language="Lua" purpose="Shows time remaining on Major shield" save_state="y" date_written="2013-04-28 10:45:35" requires="4.40" version="3.1" > <description trim="y"> <![CDATA[ Shows the time remaining on your major shield. ]]> </description> </plugin> <!-- Triggers --> <triggers> <trigger enabled="y" match="^You are ((barely |really |perfectly )?protected by the (power|grace) of|shielded by the protective armour of) (.*)\.$" name="major_up" script="Add_Timer" regexp="y" send_to="12" sequence="100" > </trigger> <trigger enabled="y" ignore_case="y" match="^your (divine protection|protective aura) (is|has been) (strengthened|extended|weakened)\.$" name="major_extend" script="Add_Timer" regexp="y" sequence="100" > </trigger> <!-- These next two signal that you failed the ritual, OR the ritual was on someone else. In either case the ritual modifiers become irrelevant. --> <trigger enabled="y" ignore_case="y" match="^((.*) loses interest in your ritual\.|You sense (.*)'s attention is elsewhere.).$" name="major_fail" script="Canceled" regexp="y" sequence="100" > </trigger> <trigger enabled="y" ignore_case="y" match="^((.*) is (protected|really protected) by the (power|grace) of (.*)|(Its|His|Her) divine protection has been (extended|strengthened|weakened)\.)$" name="major_on_another" script="Canceled" regexp="y" sequence="100" > </trigger> <trigger enabled="y" ignore_case="y" match="^ ?\* You are ((barely |really |perfectly )?protected by the (power|grace) of|shielded by the protective armour of) (.*)\. You will be protected for (.*)\.$" name="shield_check" script="Adjust_Timer" regexp="y" sequence="100" > </trigger> <trigger enabled="y" match="Your divine protection expires." name="major_down" script="Clear_Timer" sequence="100" > </trigger> <trigger enabled="y" match="Your divine protection is weakening." name="major_warning" script="Warning" sequence="100" > </trigger> <trigger enabled="y" match="You do not have any arcane protection." name="no_major" script="Clear_Timer" sequence="100" > </trigger> <!-- Message for the various ritual bonuses and penalties. --> <trigger enabled="y" ignore_case="y" match="^(It seems|You are finding it|You find it) (.*) to perform major shield because (.*)\.$" name="modifier_check" script="adjust_bonus" regexp="y" sequence="100" > </trigger> <!-- Message when you've just logged in.--> <trigger enabled="y" ignore_case="y" match="You last logged in from * and are currently logged in from *." name="logged_on" script="Unpause_Timer" sequence="100" > </trigger> <!-- Message for logging in after disconnecting but not quitting or idling out --> <trigger enabled="y" ignore_case="y" match="You are already playing." name="logged_on_already_playing" script="Already_Playing" sequence="100" > </trigger> <!-- Message indicating the next thing you enter will be your character name.--> <trigger enabled="y" ignore_case="y" match="Or, enter your current character's name" name="about_to_log_in" script="Enter_Name" sequence="100" > </trigger> <!-- Message indicating the next thing you enter will be your password. Makes the alias to capture stuff turn OFF.--> <trigger enabled="y" ignore_case="y" match=" Where all your dreams can't come true." name="about_to_enter_pass" script="Enter_Password" sequence="100" > </trigger> <!-- shouldn't need this anymore --> <trigger enabled="n" ignore_case="y" match="^You are (Miss |Mr |Mrs |Ms |Mx |Lonely |Mournful |Scary |Spooky |Wandering |Cheating |Cowardly |Brother |Sister |Mostly Reverend |Reverend |Blessed |Blessed father |Blessed mother |Blessed brother |Blessed sister |Venerable |Venerable brother |Venerable sister |Venerable father |Venerable mother |Holy |Holy brother |Holy sister |Beatus |Saint |Dr |Doctor |Professor |Butterfingers |Crafty |Crooked |Dastardly |Dishonest |Dodgy |Elusive |Evasive |Fingers |Furtive |Greased |Honest |Latent |Light-fingered |Quick-fingered |Quiet |Shady |Shifty |Silent |Slick |Sly |Tricky |Aunty |Biddy |Black |Gammer |Goodie |Goody |Gramma |Granny |Mama |Mistress |Mother |Mss |Nanna |Nanny |Old |Sister |Wee |Wicked |Young |Fat |Stuffed |Over-fed |Gimlet-eyed |Robust |Bearded |Burly |Plump |Rotund |Thin |Tiny |Mystic |Obscure |Complex |Learned |Potent |Wise |Grumpy |Cryptic |Dark |Scholarly |Grey-haired |Greybeard |Master |Mistress |Adroit |Dire |Maven |Quantum |Savant |Unseen |Archmaster |mistress |Archmage |Dame |Sir |Lady |Lord |the Amazing |the Civic-Minded |the Elegant |the Eloquent |the Helpful |the Helpful Citizen |the Stylish |the Upstanding Citizen |the Utterly Fluffy |the Wonderful |appallingly filthy |corpse looter |dull |feebleminded |i got punished |i got punished and all i got was this lousy title |i promise i won't do it again |insignificant |lying |malingering |naughty spawn |necrokleptomaniac |offensive |pillock |pointless |repentant |reprobate |shopkeeper murderer |silly spammy git |sitting in the corner |smelly |tantrum thrower |too stupid to live |vagrant |very sorry |very very sorry |waste of space |whinging |Sultan |Sultana |Shai |Sitt al-khasa |Shai |Sitt al-ri'asa |Shai |Sitt ishquaraya |Shai |Sitt a'daha |Nawab |Qasar |Mazrat |Effendi |Ya'uq |Mutasharid |Ishqaraya |Naughty Spawn |Kill Stealer |Feebleminded |Idiotic |Offensive |Corpse Looter |Cat Hating |Heathen |Foreign Dog |Infidel |Shopkeeper Murderer |Destitute |Parasitic |Hated |Cowardly |Criminal |Felon |M |Mlle |Mme |Contender |Venomous |Ancient |Exterminator |Rouge |Axe-master |Champion |Centurion |Flatulent |Competent |Cultured |Healer |Cutthroat |Knifey |Archaic |Lethal |Elementalist |Energetic |Festive |Gifted |Chef |Bloodthirsty |Impaler |Templar |Paranoid |Saintly |Crusher |Mysterious |Arcana |Diplomatic |Uncreative |Duelist |Perverse |Masterful |Fingers |Medical |Destined |Unburiable |Nasty |Nimble |Nurse |Murse |Obsolete |Old Woman |Old Man |Old |Crimewave |Antiquated |Fossilized |Mythical |Unlucky |Pious |Staffmistress |Staffmaster |Prehistoric |Rock-hard |Bruiser |Pulveriser |Literate |Wealthy |Senile |Shieldmistress |Shieldmaster |Filthy |Erratic Mechanic |Legendary |Swordmistress |Swordmaster |Terrible |Ruinous |Decrepit |Player Of Games |Headmistress |Headmaster |Multilingual |Golden |Unexpected |Unstoppable |Versatile |Virtuoso |Venerable |Opulent |Miner |Persistent |Well Travelled )?([a-z]+) ([a-z]+ )?the (.*)\.$" name="whoami" script="Set_Character_From_Whoami" regexp="y" sequence="100" > </trigger> <!-- Messages you get when you quit, shout 8, or idle out.--> <trigger enabled="y" ignore_case="y" match="^(Do come again!|Thanks for playing. See you next time.|You idled out, sorry.)$" name="logged_off" script="Pause_Timer" regexp="y" sequence="100" > </trigger> <!-- Skills output. Used to set bonus.--> <trigger enabled="n" ignore_case="y" match="faith.rituals.defensive.self * *" name="skills" script="Set_Bonus_From_Skills" sequence="100" > </trigger> </triggers> <!-- Aliases --> <aliases> <alias match="mtreset" enabled="y" send_to="12" script="Force_Reset_Timer" name="force_reset" sequence="100" > </alias> <alias match="mtset *" enabled="y" send_to="12" script="set_bonus" name="set_length" sequence="100" > </alias> <alias match="mtadd *" enabled="y" send_to="12" script="Man_Add_Timer" name="force_add" sequence="100" > </alias> <alias match="mtminus *" enabled="y" send_to="12" script="Man_Minus_Timer" name="force_minus" sequence="100" > </alias> <alias match="mtchar *" enabled="y" send_to="12" script="Man_Set_Character" name="set_char" sequence="100" > </alias> <alias enabled="y" ignore_case="y" match="help majortimer" name="helpmajor" send_to="12" sequence="100"> <send>print_help()</send> </alias> <alias match="su *" enabled="y" send_to="12" script="Switch_User" name="su" sequence="100" > </alias> <!-- Commands to, respectively, turn the whoami alias on and off. --> <alias match="mtwhoami on" enabled="y" send_to="12" script="Whoami_On" name="whoamion" sequence="100" > </alias> <alias match="mtwhoami off" enabled="y" send_to="12" script="Whoami_Off" name="whoamioff" sequence="100" > </alias> <!-- Commands to, respectively, turn the skills alias on and off. --> <alias match="mtskills on" enabled="y" send_to="12" script="Skills_On" name="skillson" sequence="100" > </alias> <alias match="mtskills off" enabled="y" send_to="12" script="Skills_Off" name="skillsoff" sequence="100" > </alias> <!-- Commands to, respectively, turn verbose mode on and off. --> <alias match="mtverbose on" enabled="y" send_to="12" script="Verbose_On" name="verboseon" sequence="100" > </alias> <alias match="mtverbose off" enabled="y" send_to="12" script="Verbose_Off" name="verboseoff" sequence="100" > </alias> <alias match="mtverbose debug" enabled="y" send_to="12" script="Verbose_Debug" name="verbosedebug" sequence="100" > </alias> <!-- Command to change the verbosity of the window. --> <alias match="mtwintext *" enabled="y" send_to="12" script="Window_Verbosity" name="windowverbosity" sequence="100" > </alias> <!-- Command to change the window position. --> <alias match="mtmove *" enabled="y" send_to="12" script="Move_Window" name="movewindow" sequence="100" > </alias> <!-- If you use mtmove without any arguments, it displays a mini helpfile. --> <alias match="mtmove" enabled="y" send_to="12" script="Move_Window_Help" name="movewindowhelp" sequence="100" > </alias> <!-- Commands to change the window position. --> <alias match="mtposx *" enabled="y" send_to="12" script="Set_X_Position" name="setxposition" sequence="100" > </alias> <alias match="mtposy *" enabled="y" send_to="12" script="Set_Y_Position" name="setyposition" sequence="100" > </alias> <!-- Command to add one performance's worth of shielding to the timer. --> <alias match="mtaddone" enabled="y" send_to="12" script="Add_Timer" name="mtaddone" sequence="100" > </alias> <!-- Command to reset the timer to zero. --> <alias match="mtclear" enabled="y" send_to="12" script="Clear_Timer" name="mtclear" sequence="100" > </alias> <!-- This is ONLY turned on when it sees the text indicating the next thing you enter will be your username. --> <alias match="*" enabled="n" send_to="12" script="Login" name="login_name" sequence="100" > </alias> </aliases> <!-- Timers --> <timers> <timer script="show_time" enabled="y" second="1.00" > </timer> </timers> <!-- Script --> <script> <![CDATA[ require "serialize" active = "" --function to set your bonus manually, triggered by the mtset alias function set_bonus (name, line, wildcards) bonus = wildcards[1] Save_Setting ("bonus", bonus) if verbose == "on" or verbose == "debug" then Note("Bonus set to ", bonus, ", which gives you a base duration of ", bonus_to_duration(bonus), " seconds.") end --if --SetChanged (true) -- world has changed... this doesn't seem necessary after all? end -- set_bonus --function to set your bonus from skills output function Set_Bonus_From_Skills (name, line, wildcards) bonus = wildcards[2] Save_Setting ("bonus", bonus) if verbose == "on" or verbose == "debug" then Note("Bonus set from skills output to ", bonus, ", which gives you a base duration of ", bonus_to_duration(bonus), ".") end --if end --Set_Bonus_From_Skills --function to calculate the duration (seconds) to add from the bonus specified function bonus_to_duration (current_bonus) return 2 * math.floor(((400 * (math.log(current_bonus + 75)) - 2082.5) / 2) + .5) end -- bonus_to_duration --function to add more time to the timer when it sees the extended/protected messages function Add_Timer () active = "yes" Save_Setting("active", active) --These next two: need to make sure that when it tries to do math on effective bonus, it actually EXISTS. If not, set both to the default. if bonus then --do nothing else bonus = 307 end --if if effective_bonus then --do nothing else effective_bonus = bonus end --if --calculate actual seconds to be added time_to_add = bonus_to_duration(effective_bonus) --if the finish time already exists we can just add the time to it. Otherwise, create it as the os time plus the time to add. if finish_time and finish_time ~= "" then finish_time = finish_time + time_to_add else finish_time = os.time () + time_to_add end -- if if verbose == "debug" then Note(time_to_add, " seconds added.") end --if --finally, save the finish time for pause/unpause purposes, reset the effective bonus to the base, and do the window Save_Setting ("finish_time", finish_time) effective_bonus = bonus show_time () end -- Add_Timer --function to reset the timer to one performance's worth function Force_Reset_Timer () finish_time = os.time () Add_Timer () end -- Force_Reset_Timer --function to manually add a specified number of minutes, triggered by the mtadd alias function Man_Add_Timer (name, line, wildcards) if finish_time and finish_time ~= "" then finish_time = finish_time + (wildcards[1]*60) show_time () else active = "yes" Save_Setting ("active", active) finish_time = os.time () + (wildcards[1]*60) show_time () end -- if Note(wildcards[1] .. " mins added to your timer.") Save_Setting ("finish_time", finish_time) end -- Man_Add_Timer --function to manually subtract a specified number of minutes, triggered by the mtminus alias function Man_Minus_Timer (name, line, wildcards) if finish_time and finish_time ~= "" then finish_time = finish_time - (wildcards[1]*60) show_time () else active = "" Save_Setting ("active", active) finish_time = "" show_time () end -- if Note(wildcards[1] .. " mins removed from your timer.") Save_Setting ("finish_time", finish_time) end -- Man_Minus_Timer --function to reset the duration, triggered by failure message, stopping the ritual, performing on someone ELSE, or target leaving. function Canceled () --reset the effective bonus because any ritual modifier message you may have gotten is now irrelevant effective_bonus = bonus end -- Canceled --a function to check what visible ritual modifiers you have and adjust the duration accordingly. function adjust_bonus (name, line, wildcards) effective_bonus = bonus modifiers = wildcards[3] text_difficulty = wildcards[2] ritual_bonuses = 0 ritual_penalties = 0 bonuses_text = "Ritual bonuses detected: " penalties_text = "Ritual penalties detected: " --messages common to all --prayed recently if string.find(modifiers, "you have been actively worshipping") then effective_bonus = effective_bonus + 7 ritual_bonuses = ritual_bonuses + 7 bonuses_text = bonuses_text .. "prayed or ritburied, " end -- if --deity pool settings if string.find(modifiers, "the hand of") then --It's 3 points for 1%. This is very rarely used, however, because it drains the pool so quickly, and so it will probably be at 1% if it's on at all. The highest setting, "10%", actually drains 1 dp per gp spent, so even the "1%" setting probably actually drains 10% of gp spent. Really can't see anybody ever setting it higher. effective_bonus = effective_bonus + 3 ritual_bonuses = ritual_bonuses + 3 bonuses_text = bonuses_text .. "deity pool settings (presumed 1%), " end -- if --other high altar OR high altar... the "other high altar" message is confusable with the "at high altar" message, so do this. if string.find(modifiers, "you are in an area consecrated to another God") then effective_bonus = effective_bonus - 45 ritual_penalties = ritual_penalties - 45 penalties_text = penalties_text .. "at wrong high altar, " elseif string.find(modifiers, "you are in a") then effective_bonus = effective_bonus + 12 ritual_bonuses = ritual_bonuses + 12 bonuses_text = bonuses_text .. "at high altar, " end -- if --near high altar, this varies if string.find(modifiers, "you are near") then --This bonus actually ranges from +3 (just barely inside the zone where you get a bonus at all) to +9(right outside an altar). I've arbitrarily put it at +6 since most of the time when you're getting this, you'll be in the same city as an altar but probably not right outside. So, a middling value seems appropriate. effective_bonus = effective_bonus + 6 ritual_bonuses = ritual_bonuses + 6 bonuses_text = bonuses_text .. "near high altar, " end -- if --witch/wizard property if string.find(modifiers, "you sense that the gods have averted their eyes from this place") then effective_bonus = effective_bonus - 45 ritual_penalties = ritual_penalties - 45 penalties_text = penalties_text .. "on witch or wizard property, " end -- if --minions if string.find(modifiers, "you are concentrating on") then penalties_text = penalties_text .. "minions (" num_minions = 0 --it's POSSIBLE that there could be multiple of the same type of whirlwind ("controlling two gigantic whirlwinds of dust") or spectre. Also, in darkness, there can be "controlling two things". Look for number words and count them. if string.find(modifiers, " two ") then modifiers, num_identicals = string.gsub(modifiers, " two ", "") num_minions = num_minions + (num_identicals * 2) penalties_text = penalties_text .. num_identicals .. " set(s) of two identical-looking minions. " end --if if string.find(modifiers, " three ") then modifiers, num_identicals = string.gsub(modifiers, " three ", "") num_minions = num_minions + (num_identicals * 3) penalties_text = penalties_text .. num_identicals .. " set(s) of three identical-looking minions, " end --if if string.find(modifiers, " four ") then modifiers, num_identicals = string.gsub(modifiers, " four ", "") num_minions = num_minions + (num_identicals * 4) penalties_text = penalties_text .. num_identicals .. " set(s) of four identical-looking minions. " end --if if string.find(modifiers, " five ") then modifiers, num_identicals = string.gsub(modifiers, " five ", "") num_minions = num_minions + (num_identicals * 5) penalties_text = penalties_text .. num_identicals .. " set(s) of five identical-looking minions. " end --if if string.find(modifiers, " six ") then modifiers, num_identicals = string.gsub(modifiers, " six ", "") num_minions = num_minions + (num_identicals * 6) penalties_text = penalties_text .. num_identicals .. " set(s) of six identical-looking minions. " end --if if string.find(modifiers, " seven ") then modifiers, num_identicals = string.gsub(modifiers, " seven ", "") num_minions = num_minions + (num_identicals * 7) penalties_text = penalties_text .. num_identicals .. " set(s) of seven identical-looking minions. " end --if if string.find(modifiers, " eight ") then modifiers, num_identicals = string.gsub(modifiers, " eight ", "") num_minions = num_minions + (num_identicals * 8) penalties_text = penalties_text .. num_identicals .. " set(s) of eight identical-looking minions. " end --if if string.find(modifiers, " nine ") then modifiers, num_identicals = string.gsub(modifiers, " nine ", "") num_minions = num_minions + (num_identicals * 9) penalties_text = penalties_text .. num_identicals .. " set(s) of nine identical-looking minions. " end --if if string.find(modifiers, " ten ") then modifiers, num_identicals = string.gsub(modifiers, " ten ", "") num_minions = num_minions + (num_identicals * 10) penalties_text = penalties_text .. num_identicals .. " set(s) of ten identical-looking minions. " end --if --count any unique devils if string.find(modifiers, " whirlwind of ") then modifiers, num_devils = string.gsub(modifiers, " whirlwind of ", "") num_minions = num_minions + num_devils penalties_text = penalties_text .. num_devils .. " unique dust devils. " end --if --unidentified minion in the dark (multiples will be "[number] things" and thus counted above) if string.find(modifiers, " something") then num_minions = num_minions + 1 penalties_text = penalties_text .. "Unidentified minion in the dark (something). " end --if --unidentified minion in the dark if string.find(modifiers, " someone") then modifiers, num_others = string.gsub(modifiers, " someone", "") num_minions = num_minions + num_others penalties_text = penalties_text .. "Unidentified minion in the dark (someone)." end --if --then see if there's a totem if string.find(modifiers, "misty woman") or string.find(modifiers, "dust bunny") or string.find(modifiers, "tall robed man") or string.find(modifiers, "rocky creature") or string.find(modifiers, "lung fish") or string.find(modifiers, "large vulture") or string.find(modifiers, "large salamander") then num_minions = num_minions + 1 penalties_text = penalties_text .. "Totem. " end --if --then see if there's a creeping doom if string.find(modifiers, " black cloud") then num_minions = num_minions + 1 penalties_text = penalties_text .. "Doom. " end --if --then see if there are unique spectres (but only ONE since multiple ones will be counted above) if string.find(modifiers, "spectre ") or string.find(modifiers, "spectre\.") or string.find(modifiers, "spectre\, ") then modifiers, _ = string.gsub(modifiers, "spectres", "") modifiers, num_spectres = string.gsub(modifiers, " spectre", "") num_minions = num_minions + num_spectres penalties_text = penalties_text .. num_spectres .. " unique spectres." end --if effective_bonus = effective_bonus - (num_minions * 4) ritual_penalties = ritual_penalties - (num_minions * 4) if num_minions > 2 then effective_bonus = effective_bonus - 1 ritual_penalties = ritual_penalties - 1 end --if penalties_text = penalties_text .. num_minions .. " minion(s) total.), " end -- if --alignment if string.find(modifiers, "you can barely feel the presence of") then effective_bonus = effective_bonus - 5 ritual_penalties = ritual_penalties - 5 penalties_text = penalties_text .. "getting out of align, " end -- if --far from a high altar if string.find(modifiers, "you are far from") then --This penalty actually ranges from -2 (just barely in the zone where you get the penalty) to -8 (as far as you can even get from an altar--although you actually get this a lot sooner). I've set it at -8 since that's what you get in Genua (if not a Gappic or Hattite) or the Ramtops (if not Pishite, Sekkite, or Gufnorkian). I think most of the time, if you're getting this one at all, you're probably getting the maximum penalty. There's a bigger "zone" that's at -8 than for anything else, I think. effective_bonus = effective_bonus - 8 ritual_penalties = ritual_penalties - 8 penalties_text = penalties_text .. "far from an altar, " end -- if --drunk if string.find(modifiers, "Hat approves of your inebriated state") then --no modifier because they cancel out penalties_text = penalties_text .. "drunk (but Hat likes drunkenness, so no overall penalty), " elseif string.find(modifiers, "you are drunk") then effective_bonus = effective_bonus - 33 ritual_penalties = ritual_penalties - 33 penalties_text = penalties_text .. "drunk, " end -- if --poisoned if string.find(modifiers, "poisoned") then effective_bonus = effective_bonus - 33 ritual_penalties = ritual_penalties - 33 penalties_text = penalties_text .. "poisoned, " end -- if --using baton. This doesn't work properly, because the actual penalty varies, but it needed to be set to SOMEthing. if string.find(modifiers, "as an external focus") then effective_bonus = effective_bonus - 56 ritual_penalties = ritual_penalties - 56 penalties_text = penalties_text .. "using a baton, " end -- if --not a regular shield, not sure if this even exists anymore if string.find(modifiers, "???") then bonuses_text = bonuses_text .. "using a fake shield, " end -- if --Pishite rain/snow/sleet bonus if string.find(modifiers, "you feel uplifted by the ") then effective_bonus = effective_bonus + 7 ritual_bonuses = ritual_bonuses + 7 bonuses_text = bonuses_text .. "rain, snow, or sleet, " end -- if --Gufnorkian if string.find(modifiers, "you are uplifted by the fluff you carry") then effective_bonus = effective_bonus + 7 ritual_bonuses = ritual_bonuses + 7 bonuses_text = bonuses_text .. "fluff in inventory, " end -- if if string.find(modifiers, "you feel at home in the fluffy surroundings") then effective_bonus = effective_bonus + 3 ritual_bonuses = ritual_bonuses + 3 bonuses_text = bonuses_text .. "somewhere fluffy, " end -- if --Gappic if string.find(modifiers, "you feel comfortable in your stylish clothes") then effective_bonus = effective_bonus + 4 ritual_bonuses = ritual_bonuses + 4 bonuses_text = bonuses_text .. "stylish clothes, " end -- if if string.find(modifiers, "you feel comfortable in your stylish surroundings") then effective_bonus = effective_bonus + 3 ritual_bonuses = ritual_bonuses + 3 bonuses_text = bonuses_text .. "stylish place, " end -- if --Sandelfonian if string.find(modifiers, "you feel more comfortable praying indoors") then effective_bonus = effective_bonus + 7 ritual_bonuses = ritual_bonuses + 7 bonuses_text = bonuses_text .. "indoors, " end -- if --Fishite if string.find(modifiers, "you are underwater") then effective_bonus = effective_bonus + 14 ritual_bonuses = ritual_bonuses + 14 bonuses_text = bonuses_text .. "underwater, " end -- if if string.find(modifiers, "you are floating in the water") then effective_bonus = effective_bonus + 7 ritual_bonuses = ritual_bonuses + 7 bonuses_text = bonuses_text .. "water surface, " end -- if --Hattite if string.find(modifiers, "Hat approves of your trespass onto the holy ground") then effective_bonus = effective_bonus + 9 ritual_bonuses = ritual_bonuses + 9 bonuses_text = bonuses_text .. "trespasser" end -- if if string.find(modifiers, "Hat approves of your company") then effective_bonus = effective_bonus + 16 ritual_bonuses = ritual_bonuses + 16 bonuses_text = bonuses_text .. "with other priests, " end -- if --Sekkite if string.find(modifiers, "you feel more confident as you battle your foes") then effective_bonus = effective_bonus + 5 ritual_bonuses = ritual_bonuses + 5 bonuses_text = bonuses_text .. "in combat, " end -- if --do some stuff here to make sure the numeric modifiers are within the ranges indicated by various difficulty messages (much harder, much easier, etc.) if ritual_bonuses == 0 then bonuses_text = "No ritual bonuses." else bonuses_text = bonuses_text .. "for a total of +" .. ritual_bonuses .. " to your bonus." end --if if ritual_penalties == 0 then penalties_text = "No ritual penalties." else penalties_text = penalties_text .. "for a total of " .. ritual_penalties .. " to your bonus." end --if if verbose == "on" or verbose == "debug" then Note(bonuses_text, " ", penalties_text, " Your bonus is ", bonus, " and your effective bonus is ", effective_bonus, ".") end -- if end -- adjust_bonus function Parse_Numbers (duration_part) num_days = 0 --start it at 0 text_days = string.sub(duration_part, 11, -6) --will look like "more than three days" so everything after "more than " up until " days" --if it's over a hundred if string.find(text_days, "hundred") then hundred_start, hundred_end, _ = string.find(text_days, " hundred") --find where "hundred" starts num_hundreds_end = hundred_start - 1 num_hundreds = string.sub (text_days, 1, num_hundreds_end) --grab the thing right before "hundred" num_days = num_days + (Parse_One_Through_Nineteen(num_hundreds) * 100) remaining_text_start = hundred_end + 2 text_days = string.sub(text_days, remaining_text_start) --we've added the n hundred days in, so now take that bit out of the text --if it was evenly divisible by a hundred there should be no "and ", but if it wasn't, we want to get rid of the "and " if string.sub(text_days, 1, 4) == "and " then text_days = string.sub(text_days, 5) end -- if end -- if --next, find any parts that indicate twenty, thirty, etc. if string.find(text_days, "ty") then _, tens_end, _ = string.find(text_days, "ty") num_tens = string.sub(text_days, 1, tens_end) --grab the thing that ends in "ty" num_tens = Parse_Tens(num_tens) --and figure out which one it is, then add it in num_days = num_days + num_tens remaining_text_start = tens_end + 2 text_days = string.sub(text_days, remaining_text_start) --we've added the n ten days in, so now take that bit out of the text --it doesn't actually matter whether there's a dash ("forty eight" vs "forty-eight") because we're skipping that character either way. end -- if --after all this the only thing even POSSIBLY left should be one, two ... nineteen. if text_days == "" then return num_days else num_days = num_days + Parse_One_Through_Nineteen(text_days) end -- if return num_days end -- Parse_Numbers function Parse_One_Through_Nineteen (text_number) if text_number == "one" then return 1 elseif text_number == "two" then return 2 elseif text_number == "three" then return 3 elseif text_number == "four" then return 4 elseif text_number == "five" then return 5 elseif text_number == "six" then return 6 elseif text_number == "seven" then return 7 elseif text_number == "eight" then return 8 elseif text_number == "nine" then return 9 elseif text_number == "ten" then return 10 elseif text_number == "eleven" then return 11 elseif text_number == "twelve" then return 12 elseif text_number == "thirteen" then return 13 elseif text_number == "fourteen" then return 14 elseif text_number == "fifteen" then return 15 elseif text_number == "sixteen" then return 16 elseif text_number == "seventeen" then return 17 elseif text_number == "eighteen" then return 18 elseif text_number == "nineteen" then return 19 else --this should NOT happen, however, if it does... return 0 end --if end --Parse_One_Through_Nineteen function Parse_Tens (text_number) if text_number == "twenty" then return 20 elseif text_number == "thirty" then return 30 elseif text_number == "forty" then return 40 elseif text_number == "fifty" then return 50 elseif text_number == "sixty" then return 60 elseif text_number == "seventy" then return 70 elseif text_number == "eighty" then return 80 elseif text_number == "ninety" then return 90 else --this should NOT happen, however, if it does... return 0 end --if end --Parse_Tens function Adjust_Timer (name, line, wildcards) duration_part = wildcards[5] -- grab the part of the line that is the textual duration and translate into seconds if duration_part == "less than five minutes" then min_duration = 1 max_duration = 299 elseif duration_part == "at least five minutes" then min_duration = 300 max_duration = 899 elseif duration_part == "at least a quarter of an hour" then min_duration = 900 max_duration = 1799 elseif duration_part == "at least half an hour" then min_duration = 1800 max_duration = 3599 elseif duration_part == "at least an hour" then min_duration = 3600 max_duration = 7199 elseif duration_part == "at least a couple of hours" then min_duration = 7200 max_duration = 21599 elseif duration_part == "more than a quarter of a day" then min_duration = 21600 max_duration = 43199 elseif duration_part == "more than half a day" then min_duration = 43200 max_duration = 86399 elseif duration_part == "more than a day" then min_duration = 86400 max_duration = 172799 else --for values over a day, they should all follow the "more than n days" pattern, parse this num_days = Parse_Numbers (duration_part) --convert days to seconds min_duration = num_days * 24 * 60 * 60 max_duration = ((num_days + 1) * 24 * 60 * 60) - 1 end -- if if finish_time and finish_time ~= "" then -- figure out time the plugin thinks is left time_left = finish_time - os.time () else time_left = 0 end -- if if time_left < min_duration then -- see if the alleged time left is within what shields says time_left = min_duration elseif time_left > max_duration then time_left = max_duration else -- do nothing end -- if active = "yes" -- set things up for the show_time function Save_Setting ("active", active) finish_time = os.time () + time_left Save_Setting ("finish_time", finish_time) show_time () end -- Adjust_Timer function Clear_Timer (name, line, wildcards) time_left = 0 active = "" finish_time = "" previous_time_left = "" Save_Setting ("finish_time", finish_time) Save_Setting ("active", active) Save_Setting ("previous_time_left", previous_time_left) end -- Clear_Timer --function to reset the time left to 20 seconds, triggered by the "weakening" message function Warning (name, line, wildcards) active = "yes" Save_Setting ("active", active) time_left = 20 finish_time = os.time () + 20 show_time () Save_Setting ("finish_time", finish_time) end -- Man_Add_Timer --Called when you log out etc. Saves the remaining time on the timer for this character. function Pause_Timer (name, line, wildcards) if active == "yes" then previous_time_left = finish_time - os.time () Note ("Paused major timer.") end -- if Save_Saveable_Variables () end -- pause_timer function Already_Playing () already_playing = true end -- Already_Playing --Called when you login etc. Grabs the remaining time for that character, if any, and starts the timer up where it left off from last time. function Unpause_Timer () active = Retrieve_Setting("active") bonus = Retrieve_Setting("bonus") if bonus == "" then bonus = 307 end -- if effective_bonus = bonus previous_time_left = Retrieve_Setting("previous_time_left") if already_playing then finish_time = Retrieve_Setting("finish_time") already_playing = nil elseif previous_time_left ~= "" then finish_time = os.time () + previous_time_left active = "yes" Note ("Unpaused major timer.") Save_Setting ("finish_time", finish_time) end -- if end -- unpause_timer function Switch_User (name, line, wildcards) --send whatever you entered, unaltered, on to the MUD Send(line) --save whichever character you su'ed from Save_Saveable_Variables () previous_character = current_character --grab the name of the character you're suing to current_character = wildcards[1] end -- Switch_User --turns the whoami alias on. Triggered by mtwhoami on function Whoami_On () world.EnableTrigger("whoami", true) SetVariable("whoami", "on") end --Whoami_On --turns the whoami alias off. Triggered by mtwhoami off function Whoami_Off () world.EnableTrigger("whoami", false) SetVariable("whoami", "") end --Whoami_Off --turns the skills alias on. Triggered by mtskills on function Skills_On () world.EnableTrigger("skills", true) SetVariable("skills", "on") end --Skills_On --turns the skills alias off. Triggered by mtskills off function Skills_Off () world.EnableTrigger("skills", false) SetVariable("skills", "") end --Skills_Off --turns verbose mode on. Triggered by mtverbose on. This is global, not per character. Verbose mode causes extra messages in some places. (Extra messages: saying how your bonus is affected by whatever ritual modifiers it sees; saying what bonus you've set it (manually or via skills output) to and what base duration that gives you; telling you when it detects which character you're using.) function Verbose_On () verbose = "on" SetVariable("verbose", "on") end --Verbose_On --debug mode, even more messages. (Tells you when it saves a character-specific setting, tells you how much time has been added.) function Verbose_Debug () verbose = "debug" SetVariable("verbose", "debug") end --Verbose_Debug --turns verbose mode off. function Verbose_Off () verbose = "" SetVariable("verbose", "") end --Verbose_Off --Triggered by the text, "Or, enter your current character's name". When that shows up the next thing entered might be your login, so enable the alias to grab whatever you enter. function Enter_Name () world.EnableAlias("login_name", true) end -- Enter_Name --Triggered by the text, " Where all your dreams can't come true.", which is part of the thing you get AFTER you enter your name. Hopefully this will stop it grabbing your password if you enter your name too quickly. function Enter_Password () world.EnableAlias("login_name", false) end -- Enter_Password function Login (name, line, wildcards) --send whatever you entered, unaltered, on to the MUD Send(line) --save whatever you entered as your current character --but make sure it's not a *command* instead of a character name. Not that it hurts per se, but it can clutter up the save file. if line ~= "q" and line ~= "m" and line ~= "d" and line ~= "r" and line ~= "u" and line ~= "l" and line ~= "p" and line ~= "f" and line ~= "n" and line ~= "g" then current_character = line if verbose == "on" or verbose == "debug" then Note("[Major Timer] Character detected: ", current_character) end -- if end -- if --turn the alias off again. world.EnableAlias("login_name", false) end -- Login function Set_Character_From_Whoami (name, line, wildcards) potential_character = wildcards[2] if potential_character == "not" or potential_character == "already" or potential_character == "remembering" or potential_character == "keeping" or potential_character == "unsure" or potential_character == "crouching" or potential_character == "kneeling" or potential_character == "lying" or potential_character == "lounging" or potential_character == "meditating" or potential_character == "sitting" or potential_character == "squatting" or potential_character == "standing" then --do nothing, this stops it from setting itself from "you are not holding", "you are already wearing the", position stuff, etc. else current_character = potential_character if verbose == "on" or verbose == "debug" then Note("[Major Timer] Character detected: ", current_character) end -- if end -- if end -- Set_Character_From_Whoami --manually set the character with mtchar function Man_Set_Character (name, line, wildcards) current_character = wildcards[1] if verbose == "on" or verbose == "debug" then Note("Character set: ", current_character) end -- if Unpause_Timer () end -- Man_Set_Character --move the window to an autoposition function Move_Window (name, line, wildcards) absolute_positioning = "false" SetVariable("absolute_positioning", "false") --some handling to make it not throw up if you give it a string instead of a number window_position = tonumber(wildcards[1]) if window_position == nil then window_position = 5 end -- if SetVariable("window_position", window_position) show_time () end -- Move_Window --set the absolute position of the window (x-position is set separately from y) function Set_X_Position (name, line, wildcards) absolute_positioning = "true" SetVariable("absolute_positioning", "true") --in case of garbage input x_position = tonumber(wildcards[1]) if x_position == nil then x_position = 0 end -- if SetVariable("x_position", x_position) show_time () end -- Set_X_Position function Set_Y_Position (name, line, wildcards) absolute_positioning = "true" SetVariable("absolute_positioning", "true") --in case of garbage input y_position = tonumber(wildcards[1]) if y_position == nil then y_position = 0 end -- if SetVariable("y_position", y_position) show_time () end -- Set_Y_Position function Window_Verbosity (name, line, wildcards) if wildcards[1] == "verbose" or wildcards[1] == "brief" then window_verbosity = wildcards[1] SetVariable("window_verbosity", wildcards[1]) show_time () else Note ("Acceptable arguments are 'verbose' or 'brief'.") end -- if end -- Window_Verbosity --actually makes the window showing the remaining time. function show_time (name, line, wildcards) if active == "yes" and finish_time ~= "" then time_left = finish_time - os.time () if window_verbosity == "brief" then start_text = "" warning_text = "Expiring!" else start_text = "Major shield expires in: " warning_text = "Shield due to drop!" end -- if if time_left <= 0 then --These next two lines are so that there will not be a finish_time that's in the past. Otherwise, if it thought it should have dropped five minutes ago and you added four minutes of shielding, it would think it should have dropped one minute ago, when it should actually think it's now due to drop in four minutes. time_left = 0 finish_time = os.time () text = warning_text elseif time_left < 60 then text = string.format (start_text .. time_left .. " seconds.") elseif time_left >= 60 and time_left < 3600 then mins_left = string.format ("%3.1f", (time_left / 60)) text = string.format (start_text .. mins_left .. " minutes.") elseif time_left >= 3600 and time_left < 86400 then hrs_left = string.format ("%3.1f", ((time_left / 60)/60)) text = string.format (start_text .. hrs_left .. " hours.") elseif time_left >= 86400 then days_left = string.format ("%i", (((time_left / 60)/60))/24) hrs_left = string.format ("%3.1f", (((time_left - (days_left*60*60*24))/60)/60)) text = string.format (start_text .. days_left .. " days and " .. hrs_left .. " hours.") end -- if max_width = (WindowTextWidth (win, "fn", text)) + 10 if window_position == null then window_position = 5 -- auto-position: top middle end -- if if time_left < 60 then TEXT_COLOUR = ColourNameToRGB ("red") else TEXT_COLOUR = ColourNameToRGB ("black") end -- if -- recreate the window the correct size, either in an auto-position or in an absolute position if absolute_positioning == "true" then if x_position == null then x_position = 0 end -- if if y_position == null then y_position = 0 end -- if WindowCreate (win, x_position, y_position, -- left, top max_width, -- width font_height + 10, -- height window_position, -- auto-position: top middle 2, -- flags; this means that it's using absolute positioning ColourNameToRGB ("lightgoldenrodyellow")) WindowSetZOrder (win, 20) else WindowCreate (win, 0, 0, -- left, top (auto-positions) max_width, -- width font_height + 10, -- height window_position, -- auto-position: top middle 0, -- flags ColourNameToRGB ("lightgoldenrodyellow")) WindowSetZOrder (win, 20) end -- if WindowText (win, "fn", text, -- text 5, 5, 0, 0, -- rectangle TEXT_COLOUR, -- colour false) -- not Unicode WindowShow (win, true) else WindowShow (win, false) end -- if active end -- show_time function OnPluginInstall () win = GetPluginID () font_id = "fn" font_name = "Comic Sans MS" -- the actual font -- make win so I can grab the font info WindowCreate (win, 0, 0, 1, 1, -- 1 x 1 pixel 1, -- position - irrelevant 0, -- flags 0) -- background colour check (WindowFont (win, font_id, font_name, 8)) -- normal font_height = WindowFontInfo (win, font_id, 1) -- height --load settings for this character current_character = GetVariable("current_character") or "default" active = Retrieve_Setting("active") or "" finish_time = Retrieve_Setting("finish_time") or "" previous_time_left = Retrieve_Setting("previous_time_left") or "" --if we have no bonus set for this character, use this arbitrary default bonus (guildmax and all 13s) bonus = Retrieve_Setting("bonus") or 307 --and get these global settings verbose = GetVariable("verbose") or "" whoami = GetVariable("whoami") or "" skills = GetVariable("skills") or "" window_position = GetVariable("window_position") or 5 window_position = tonumber(window_position) if window_position == nil then window_position = 5 end -- if absolute_positioning = GetVariable("absolute_positioning") or "" x_position = GetVariable("x_position") or 0 y_position = GetVariable("y_position") or 0 window_verbosity = GetVariable("window_verbosity") or "verbose" if whoami == "on" then world.EnableTrigger("whoami", true) else world.EnableTrigger("whoami", false) end -- if if skills == "on" then world.EnableTrigger("skills", true) else world.EnableTrigger("skills", false) end -- if end -- OnPluginInstall function OnPluginDisable () WindowShow (win, false) end -- OnPluginDisable ------------------------------------------------------------------------------------------- -- on saving state, convert Lua table back into string variable save_simple is for simple -- tables that do not have cycles (self-reference) or refer to other tables ------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- -- Before, it was using serialize.save_simple. However, that seemed to be adding a bunch -- of backslashes and quotes to the file every time, so that the variables it saved got -- increasingly longer. THIS seems to work fine, though. ------------------------------------------------------------------------------------------- --use this by feeding them a setting NAME, as TEXT, and then the setting itself; e.g. Save_Setting("bonus", bonus) function Save_Setting (setting_name, setting) variable_name = string.format (current_character .. "_" .. setting_name) if setting then SetVariable (variable_name, setting) if verbose == "debug" then Note("Saved: ", variable_name, " as ", setting) end--if else --but, it should not be nil. This is just in case. SetVariable (variable_name, "") if verbose == "debug" then Note("Saved: ", variable_name, " as empty string") end --if end -- if end -- Save_Setting --This one however only needs the name (again, as TEXT); it will return the value to set as the setting itself. E.g. bonus = Retrieve_Setting ("bonus") function Retrieve_Setting (setting_name) variable_name = string.format (current_character .. "_" .. setting_name) setting = GetVariable(variable_name) or "" return setting end -- Retrieve_Setting function Save_Saveable_Variables () Save_Setting ("window_position", window_position) Save_Setting ("x_position", x_position) Save_Setting ("y_position", y_position) Save_Setting ("absolute_positioning", absolute_positioning) Save_Setting ("window_verbosity", window_verbosity) SetVariable ("current_character", current_character) if active == "yes" and finish_time ~= "" then Save_Setting ("finish_time", finish_time) previous_time_left = finish_time - os.time () Save_Setting ("previous_time_left", previous_time_left) Save_Setting ("active", "yes") else Save_Setting ("finish_time", "") Save_Setting ("previous_time_left", "") Save_Setting ("active", "") end -- if if bonus then Save_Setting ("bonus", bonus) end -- if end -- function Save_Saveable_Variables function OnPluginSaveState () Save_Saveable_Variables () end -- function OnPluginSaveState function OnWorldSave () Save_Saveable_Variables () end -- function function Move_Window_Help() Note([[The command mtmove sets the window position to one of a few presets. It needs an argument, e.g. "mtmove 5" or "mtmove 10". Here are the acceptable arguments and where they put the window: 4 = top left 5 = center left-right at top (the default) 6 = top right 7 = on right, center top-bottom 8 = on right, at bottom 9 = center left-right at bottom 10 = on left, at bottom 11 = on left, center top-bottom 12 = centre all If none of these are what you want, then use mtposx and mtposy instead--they let you put the window wherever you want within the main MUSHclient window. * mtposx <number> Sets the x-position. 0 is all the way to the left, and the default. Positive numbers move it rightwards. * mtposy <number> Sets the y-position. 0 is all the way at the top, and the default. Positive numbers move it downwards. Using either mtposx or mtposy will override the autoposition. ]]) end -- Move_Window_Help function print_help() Note([[Plugin Help:Major Timer This plugin produces a small window showing the time remaining on your faith shield. This currently only works for Major Shield. Minor Shield, although it stacks with Major Shield, has a different duration formula. It does, however, have exactly the same success message, so using Minor Shield will confuse the plugin. It also doesn't work well for having other people perform Major Shield on you: it will use *your* bonus to determine the duration. It can set itself either from actually performing Major Shield (if you've used mtset to set your bonus), or (roughly) from the output of the "shields" command. It can remember bonus information and time remaining on a shield on a per-character basis. Therefore, you can log off with a shield running without it counting the time spent logged off. It should detect which character you're logging in as when you log in or su (although if you have an alias for su that's something other than "su", this part will not work). It can detect ritual bonuses and penalties (for example, being at a high altar) and will adjust your effective bonus--and therefore duration--accordingly. As the bonuses and penalties for being near or far from a high altar vary somewhat depending on exact distance, it may still be off by a few seconds. The following commands are recognized: * help majortimer Displays this help file. * mtset <number> Set your fa.ri.de.se bonus, from which durations are derived. Eg. A 300 bonus should be entered as 'mtset 300'. * mtadd <number> Manually add time in minutes to your shield timer. Eg. 'mtadd 2' will add 2 minutes to the timer. * mtminus <number> Manually minus time in minutes from your shield timer. Eg. 'mtminus 2' will take 2 minutes from the timer. * mtreset Sets the timer back to 1 shield's duration in length. * mtaddone Manually adds one performance's worth of shielding, using the most recent value for effective bonus. * mtclear Clears the timer. * mtchar <name> Manually sets the current character and loads any previous settings for that character. * mtwhoami [on|off] Turns the trigger for whoami output on or off. "On" lets the plugin detect the output of the MUD's "whoami" command, and set your current character accordingly. "Off" is the default, as the trigger can easily be triggered incorrectly (for example by whoami output in finger info, or by unrelated messages with a similar format). * mtskills [on|off] Turns the trigger for skills output on or off. When on, it can detect the line for f.r.d.s, but only if the output is in list format. Off by default. * mtverbose [on|off] Turns verbose mode on or off. In verbose mode: extra messages are displayed when: you set your bonus (or it's set from skills output), you perform MS with ritual modifiers, and when you set your character (manually or through whoami). Off by default. * mtmove <number> Sets the window position to one of a few auto-positions: 4 = top left 5 = center left-right at top (the default) 6 = top right 7 = on right, center top-bottom 8 = on right, at bottom 9 = center left-right at bottom 10 = on left, at bottom 11 = on left, center top-bottom 12 = centre all Typing mtmove without an argument will display a mini helpfile about using mtmove. * mtposx <number> Sets the x-position of the window. 0 is all the way to the left, and the default. * mtposy <number> Sets the y-position of the window. 0 is all the way at the top, and the default. Using either mtposx or mtposy will override the autoposition. * mtwintext [verbose|brief] This changes the text in the window. Verbose: the default. "Major shield expires in: 4.2 hours." "Shield due to drop!" Brief: "4.2 hours." "Expiring!" ]]) end ]]></script> </muclient>