General scripts
Always Attack
Description: The 't' key by default toggles your attack, which can be very frustrating in the middle of a fight since you don't know if hitting 't' again will start or stop combat. Use this and you'll know you'll always be attacking.<br>
How to use: Bind 't' to this script through Key Bindings under the game's Main Menu.
Note: unfortunately this reportedly doesn't work with certain Unit frame mods, like NerfedUI, which disable PlayerFrame.
-- Always attack
if ( not PlayerFrame.inCombat ) then
CastSpellByName("Attack")
end
Only show Available items at trainers
Description: Makes trainers only show you available training by default.<br>
How to use: Execute on event: TRAINER_SHOW
-- Only show available items at trainers
SetTrainerServiceTypeFilter("unavailable", 0)
Play a sound when you're attacked.
Description: Notify you when you are being attacked. I like the heads up. You might prefer a different sound.<br>
How to use: Execute on event: PLAYER_REGEN_DISABLED
-- Play the sound specified when you are being attacked
PlaySound("igQuestFailed")
Say woot and dance when you level
Description: Same as title.<br>
How to use: Execute on event: PLAYER_LEVEL_UP
-- Say woot and dance whenever you level up
SendChatMessage("woot!")
DoEmote("dance","player")
Friendly Party Roll for Chest
If you are playing with friends, this script can roll on chests for the entire party, this is mostly for people playing with friends, as it can be abused otherwise. If you have a set of friends you play with frequently, you can set this up to quickly roll on chests so that someone else doesn't nick the loot first :)
Requirements: none, just bind to a macro if you want.
if (GetNumPartyMembers() == 0) then
PlaySound("igQuestFailed")
DEFAULT_CHAT_FRAME:AddMessage("You cannot roll, because you are not in a party");
else
SendChatMessage("--[ ROLLING FOR CHEST ] ----------------------", "PARTY");
-- Create some global variables
winner = 0; -- the winner
winningValue = -1; -- the winning value
randomValues = {};
partyMembers = {};
randomValues[0] = math.random(1, 100);
partyMembers[0] = UnitName("player");
for count = 1, GetNumPartyMembers(), 1 do
randomValues[count] = math.random(1, 100);
partyMembers[count] = UnitName("party" .. count);
end
-- Work out who the winner is before printing it.
for count = 0, GetNumPartyMembers(), 1 do
if (randomValues[count] > winningValue) then
winner = count;
winningValue = randomValues[count];
end
end
-- Print values...
for count = 0, GetNumPartyMembers(), 1 do
s = partyMembers[count] .. ": " .. randomValues[count];
if (winner == count) then
s = "> " .. string.upper(s) .. " < ";
else
s = " " .. s
end
SendChatMessage(s, "PARTY");
end
SendChatMessage("------------------------------------------------------------", "PARTY");
end
Quest Status Announce to Party
Description: This helps with the tedious back and forth chat of asking and announcing how many of each items you have left to collect. It reports the status of your currently highlighted quest to your party. No more typing, "I need 6 more of this, 4 more of that, and 3 of the other".<br>
How to use: Bind to key, or put in a macro.
-- Announce the status of your quest items to your party
t={}
i=GetNumQuestLeaderBoards()
for j=1,i,1 do
a1,a2,a3=GetQuestLogLeaderBoard(j)
tinsert(t,a1)
end
SendChatMessage(table.concat(t,', '),"PARTY")
Bandage (complex), or The Only Bandage Macro You'll Ever Need
Description: This finds and uses the smallest bandage possible to heal your target (default: self) to the desired level. The default is 80%.<br>
How to use: Bind to key.
Note: after refining this code within LuaSlinger, I moved it out to a standalone Addon called SmartBandage, which has numerous enhancements over this script. However, this is a good example of some complex lua coding within LuaSlinger.
-- Use the smallest bandage possible. Find it anywhere in the player's
-- inventory. Make sure the target receives healing, even if it's not optimal.
-- The algorithm is as follows:
-- Our goal is to heal the target to at least 80 percent of his/her maximum
-- (adjustable below). Identify the smallest type of bandage that can meet the
-- healing need. Try to find it in the player's inventory. If not found, try
-- the next better bandage and so on up the line. If we didn't find a bandage,
-- then go back and try to find the bandage just smaller than the desired bandage.
-- If not found, try the next smaller bandage and so on.
--
-- NOTE: This requires the FindContainerItemByName() and p() functions found
-- elsewhere on this wiki.
--
TARGET_HEALTH_PCT = 80
-- these MUST be listed in ascending order of potency
-- All known bandages are included as of 11/05/2005
bandages = {
{"Linen Bandage", 66},
{"Heavy Linen Bandage", 114},
{"Wool Bandage", 161},
{"Heavy Wool Bandage", 301},
{"Silk Bandage", 400},
{"Heavy Silk Bandage", 640},
{"Mageweave Bandage", 800},
{"Heavy Mageweave Bandage", 1104},
{"Runecloth Bandage", 1360},
{"Heavy Runecloth Bandage", 2000}
}
if (not UnitIsFriend("player","target")) then
TargetUnit("player")
end
if (not UnitInParty("target")) then
return
end
need = (UnitHealthMax("target") * TARGET_HEALTH_PCT/100) - UnitHealth("target")
if (need <= 0) then
p("## Bandage: not enough need")
return
end
desiredBandageIdx = table.getn(bandages)
for idx,b in bandages do
if (b[2] >= need) then
desiredBandageIdx = idx
break
end
end
b = bandages[desiredBandageIdx]
p("## Bandage: "..UnitName("target").." needs "..need.." HP, I'll try to use a "..b[1].."("..b[2]..")")
bag, slot = nil, nil
for i = desiredBandageIdx, table.getn(bandages) do
bag, slot = FindContainerItemByName(bandages[i][1])
if (bag ~= nil) then
p("## Bandage: Using "..bandages[i][1].." ("..bandages[i][2]..") on "..UnitName("target"))
UseContainerItem(bag, slot)
return
end
end
for i = desiredBandageIdx - 1, 1, -1 do
bag, slot = FindContainerItemByName(bandages[i][1])
if (bag ~= nil) then
p("## Bandage: Using "..bandages[i][1].." ("..bandages[i][2]..") on "..UnitName("target"))
UseContainerItem(bag, slot)
return
end
end
p("## Bandage: Sorry, couldn't find a bandage")
Eat some food
Description: Similar to the Complex Bandage script, it uses the best food available to heal you up.
How to use: bind to key or execute on demand
-- Use the most approriate food to heal. Find it anywhere in the player's
-- inventory.
-- The algorithm is as follows:
-- Our goal is to heal the target to at least 95 percent of his/her maximum
-- (adjustable below).
-- Identify the best food to eat to meet the healing need.
-- Try to find it in the player's inventory. If not found, try
-- the next food item and so on up the line. If we didn't find a bandage,
-- then go back and try to find the bandage just smaller than the desired bandage.
-- If not found, try the next smaller bandage and so on.
--
-- NOTE: This requires the FindContainerItemByName() and p() functions found
-- elsewhere on this wiki.
--
TARGET_HEALTH_PCT = 95
-- these MUST be listed in ascending order of potency
-- Keep in mind not All of the food is listed here. There are dozens,
-- potentially hundreds of food items. The ones listed here are basic
-- and common, you can change them to suit your needs
fooditems = {
{"Brilliant Smallfish", 61},
{"Slitherskin Mackerel", 61},
{"Charred Wolf Meat", 61},
{"Conjured Bread", 243},
{"Tel'Abim Banana", 243},
{"Smoked Bear Meat", 243},
{"Delicious Cave Mold", 875},
{"Wild Hog Shank", 875},
{"Mystery Stew", 875},
{"Mulgore Spice Bread", 875},
{"Frog Leg Stew", 875},
{"Soft Banana Bread", 1392},
{"Spider Sausage", 1392},
}
if (not UnitIsFriend("player","target")) then
TargetUnit("player")
end
if (not UnitInParty("target")) then
return
end
need = (UnitHealthMax("target") * TARGET_HEALTH_PCT/100) - UnitHealth("target")
if (need <= 0) then
p("## You don't need to eat anything right now")
return
end
desiredBandageIdx = table.getn(bandages)
for idx,b in bandages do
if (b[2] >= need) then
desiredBandageIdx = idx
break
end
end
b = fooditems[desiredFooditemsIdx]
p("## Bandage: "..UnitName("target").." needs "..need.." HP, I'll try to use a "..b[1].."("..b[2]..")")
bag, slot = nil, nil
for i = desiredFooditemsIdx, table.getn(fooditems) do
bag, slot = FindContainerItemByName(fooditems[i][1])
if (bag ~= nil) then
p("## Food: Eating"..fooditems[i][1].." ("..fooditems[i][2]..") on "..UnitName("target"))
UseContainerItem(bag, slot)
return
end
end
for i = desiredFooditemsIdx - 1, 1, -1 do
bag, slot = FindContainerItemByName(fooditems[i][1])
if (bag ~= nil) then
p("## Fooditems: Using "..fooditems[i][1].." ("..fooditems[i][2]..") on "..UnitName("target"))
UseContainerItem(bag, slot)
return
end
end
p("## Sorry, could not find food, make some or buy some")
Dump out what's in each action bar slot
Description: This script tells you what is on each of your action bars, this is helpful when using some of the other scripts in the LuaSlinger library.<br>
How to use: bind to key or execute on demand
-- Dump out whats in each action bar slot
for i=1, 120, 1 do
text = GetActionText(i)
if (text==nil) then
text=GetActionTexture(i)
end
if (text==nil) then
text=''
end
DEFAULT_CHAT_FRAME:AddMessage(i..' :: '..text)
end
Change the action bar automatically based on the target's distance (advanced)
Description: Unfortunately Blizzard provides no event we can catch to know when the target crosses into mele range, so in this case we constantly poll the target's distance. The way we poll is by hooking the PlayerFrame_OnUpdate function, which is a built-in WoW function that gets called every screen refresh. We save the original function and call it every time, but we do our thing only once every .3 seconds. In this example I chose to use page 1 for mele and page 3 for ranged. Put this code in your Library and it will automatically start working. Remember: LuaSlinger gives you rope... don't hang yourself :-).<br>
How to use: Just put this in your Library and Reload, it will automatically start working.
-- Update action bars based on target's distance. Hook PlayerFrame's OnUpdate to do this.
function stkRangeCheck()
if (UnitName("target")) then
local desiredPage
if (CheckInteractDistance("target", 1)) then
desiredPage = 1
else
desiredPage = 3
end
if (CURRENT_ACTIONBAR_PAGE ~= desiredPage) then
CURRENT_ACTIONBAR_PAGE = desiredPage
ChangeActionBarPage()
end
end
end
function stkRangeCheckOnUpdate(elapsed)
if (GetTime() >= stkLastRangeCheck + .3) then
stkLastRangeCheck = GetTime()
stkRangeCheck()
end
stkOriginalPlayerFrameOnUpdate(elapsed)
end
if (stkOriginalPlayerFrameOnUpdate == nil) then
-- only want to do this once
stkOriginalPlayerFrameOnUpdate = PlayerFrame_OnUpdate
stkLastRangeCheck = GetTime()
end
-- hook PlayerFrame_OnUpdate
PlayerFrame_OnUpdate = stkRangeCheckOnUpdate
Automatically switch your action bar back to ranged page when clearing your target
Description: This goes with the above script that changes the action bar automatically based on the target's distance. Use this to automatically switch back to your ranged bar when clearing your target.<br>
How to use: Execute on event: <tt>PLAYER_TARGET_CHANGED</tt>
if (not UnitName("target")) then
CURRENT_ACTIONBAR_PAGE = 3
ChangeActionBarPage()
end
Chat Parser
Description: This simple chat parser will watch all chats, whispers, says, and yells for text patterns you specify. Then you can dump then out and clear them. This is more a proof of concept on how to monitor chat than anything, in reality you'd probably want to do something more interesting.<br>
How to use: Execute on events (put them all in the event name box, comma-separated): CHAT_MSG_CHANNEL, CHAT_MSG_WHISPER, CHAT_MSG_SAY and CHAT_MSG_YELL.
if (not savedText) then
savedText = {}
end
-- full regex is supported, see http://www.lua.org/manual/5.0/manual.html#5.3
interestingPatterns = {
"WTS",
"%dg",
"UBRS",
}
for i, pat in interestingPatterns do
if (string.find(msg, pat)) then
table.insert(savedText, author..": "..msg)
end
end
One more script to dump out and clear what the script has captured:
-- show interesting text
DEFAULT_CHAT_FRAME:AddMessage("Found "..table.getn(savedText).." interesting messages.")
for i, text in savedText do
DEFAULT_CHAT_FRAME:AddMessage(text)
end
-- and reset it
savedText = {}