

|
|
Source code |
1 2 3 |
PickupBagItem(GetBagItemInfo(1)) -- pickup item in bag slot 1 (slot 1 now in cursor) PickupBagItem(GetBagItemInfo(2)) -- swap with item in bag slot 2 (slot 2 now in cursor) PickupBagItem(GetBagItemInfo(1)) -- Put item 2 into bag slot 1 (cursor empty) |
(To forum admins: I wish you could make it easy to love you...)|
|
Source code |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
debug_string = ""
function DEBUG_MSG(new_txt)
debug_string = debug_string .. "\n" .. new_txt
Chat_CopyToClipboard(string.sub(debug_string, -1023))
ChatFrame1:AddMessage(new_txt);
end
FIRST_SLOT_TO_SORT = 1
LAST_SLOT_TO_SORT = 30
function GetBagItemOrderBy(index)
local bagIndex, icon, name, itemCount, locked, itemQuality = GetBagItemInfo(index);
if icon == nil or name == "" then
-- DEBUG_MSG("Slot "..index.." is empty");
return nil;
end
-- DEBUG_MSG("GetBagItemOrderBy (" ..index.. "-"..bagIndex.."-" .. name..")");
-- DEBUG_MSG("GetBagItemOrderBy (" .. string.sub(name, -4)..")");
if string.sub(name, -4) ~= ' Egg' then
-- DEBUG_MSG("Slot "..index.." is blocked");
return -1, -1;
end
tooltip = GameTooltip;
tooltip:SetBagItem(bagIndex);
tooltip:Hide();
local lines = Sol.tooltip.ReadTooltip(tooltip);
local numLines = #(lines.left);
local element = nil;
local level = nil;
local order_by = 0;
for i = 1, numLines do
txt = lines.left[i].text
if string.sub(txt, 1, 9) == "Element: " then
element = string.sub(txt, 10);
-- DEBUG_MSG("GetBagItemOrderBy E(" .. element ..")");
end
if string.sub(txt, 1, 7) == "Level: " then
level = string.sub(txt, 8);
-- DEBUG_MSG("GetBagItemOrderBy L(" .. level ..")");
end
end
order_by = 0
if name == 'Rune Pet Egg' then
order_by = order_by + 6000000;
end
if element == 'Fire' then
order_by = order_by + 5000000;
elseif element == 'Water' then
order_by = order_by + 4000000;
elseif element == 'Wind' then
order_by = order_by + 3000000;
elseif element == 'Dark' then
order_by = order_by + 2000000;
elseif element == 'Earth' then
order_by = order_by + 1000000;
elseif name == 'Rune Pet Egg' then
order_by = order_by + 0; -- Runic eggs don't have the element in description, still I wan't to sort them
else
-- DEBUG_MSG("ERROR: An egg with not recognized ELEMENT. Not moving.");
-- in particular: I don't move Holy Pet Eggs, although it would make sense to sort them as the first or the last
return -1, -1
end
order_by = order_by + tonumber(level) * 1000;
if name == 'Wild Pet Egg' then
order_by = order_by + 4;
elseif name == 'Natural Pet Egg' then
order_by = order_by + 3;
elseif name == 'Amazing Pet Egg' then
order_by = order_by + 2;
elseif name == 'Magical Pet Egg' then
order_by = order_by + 1;
elseif name == 'Rune Pet Egg' then
order_by = order_by + 0; -- already updated above as the highest prio
else
-- DEBUG_MSG("ERROR: An egg with not recognized NAME. Not moving.");
return -1, -1
end
return bagIndex, order_by;
end
function SwapItemsInBag(p1, p2)
if initial_bag_info[p1] == nil or initial_bag_info[p2] == nil then
-- DEBUG_MSG("ERROR: SwapItemsInBag should be called with both position not empty!");
return;
end
PickupBagItem(GetBagItemInfo(p1)) -- pick up item in bag slot p1 (slot p1 now in cursor)
PickupBagItem(GetBagItemInfo(p2)) -- swap with item in bag slot p2 (slot p2 now in cursor)
PickupBagItem(GetBagItemInfo(p1)) -- put down item p2 into bag slot p1 (cursor empty)
-- update source_position<->target_position accordingly:
....
end
function MoveItemInBag(from_item_pos, to_empty_pos)
....
PickupBagItem(GetBagItemInfo(from_item_pos)); -- pick up item in bag slot from_item_pos (slot from_item_pos now in cursor)
PickupBagItem(GetBagItemInfo(to_empty_pos)); -- put down item from_item_pos into empty bag slot to_empty_pos (cursor empty)
...
end
[....]
----------------
--- START OF ACTUAL CODE
----------------
----------------
-- 1. loop over bag; for each item store bag_index, order_by;
-- initially set final_position == initial_position
----------------
[...]
----------------
-- 2. prepare sorting info
----------------
for b = FIRST_SLOT_TO_SORT, LAST_SLOT_TO_SORT do
[...]
end
----------------
-- 3. perform actual sorting
-- loop over bag from position 1 onwards; move correct item to this position
----------------
for b = FIRST_SLOT_TO_SORT, LAST_SLOT_TO_SORT do
take_item_from = initial_position[b]
if take_item_from ~= nil and take_item_from ~= b then
if initial_bag_info[b] == nil then
MoveItemInBag(take_item_from, b)
else
SwapItemsInBag(take_item_from, b)
end
end
end
|
|
|
Source code |
1 |
/mh sort_eggs_EN |
I hope it's good enough for the forum admins - at least no one will hurt himself accidentally - only those who know what they are doing (and have read this description) will be able to use it.)

This post has been edited 2 times, last edit by "Uure" (Jan 19th 2015, 11:05pm)
|
|
Source code |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
debug_string = ""
function DEBUG_MSG(new_txt)
debug_string = debug_string .. "\n" .. new_txt
Chat_CopyToClipboard(string.sub(debug_string, -1023))
ChatFrame1:AddMessage(new_txt);
end
FIRST_SLOT_TO_SORT = 1
LAST_SLOT_TO_SORT = 30
initial_bag_info = {} -- access index: initial (during actual swapping: current) position; each item contains two keys: order_by and final_position
initial_position = {} -- access index: final position; returns initial (during actual swapping: current) position of the item which should end up at this final position
function DebugTables()
for b = FIRST_SLOT_TO_SORT, LAST_SLOT_TO_SORT do
if initial_bag_info[b] ~= nil then
DEBUG_MSG("initial_bag_info[" ..b.. "]: o_by " .. initial_bag_info[b]["order_by"].. "; final_pos " .. initial_bag_info[b]["final_position"]);
else
DEBUG_MSG("initial_bag_info[" ..b.. "] == nil");
end
end
for b = FIRST_SLOT_TO_SORT, LAST_SLOT_TO_SORT do
if initial_position[b] ~= nil then
DEBUG_MSG("initial_position[" ..b.. "]: " .. initial_position[b]);
else
DEBUG_MSG("initial_position[" ..b.. "] == nil");
end
end
end
function GetBagItemOrderBy(index)
local bagIndex, icon, name, itemCount, locked, itemQuality = GetBagItemInfo(index);
if icon == nil or name == "" then
-- empty
return nil;
end
if string.sub(name, -4) ~= ' Egg' then
-- not Egg: not moving
return -1, -1;
end
tooltip = GameTooltip;
tooltip:SetBagItem(bagIndex);
tooltip:Hide();
local lines = Sol.tooltip.ReadTooltip(tooltip);
local numLines = #(lines.left);
local element = nil;
local level = nil;
local order_by = 0;
for i = 1, numLines do
txt = lines.left[i].text
if string.sub(txt, 1, 9) == "Element: " then
element = string.sub(txt, 10);
end
if string.sub(txt, 1, 7) == "Level: " then
level = string.sub(txt, 8);
end
end
order_by = 0
if name == 'Rune Pet Egg' then
order_by = order_by + 6000000;
end
if element == 'Fire' then
order_by = order_by + 5000000;
elseif element == 'Water' then
order_by = order_by + 4000000;
elseif element == 'Wind' then
order_by = order_by + 3000000;
elseif element == 'Dark' then
order_by = order_by + 2000000;
elseif element == 'Earth' then
order_by = order_by + 1000000;
elseif name == 'Rune Pet Egg' then
order_by = order_by + 0; -- Runic eggs don't have the element in description, still I wan't to sort them
else
-- unrecognized (not Egg, or Holy etc.) => not moving
return -1, -1
end
order_by = order_by + tonumber(level) * 1000;
if name == 'Wild Pet Egg' then
order_by = order_by + 4;
elseif name == 'Natural Pet Egg' then
order_by = order_by + 3;
elseif name == 'Amazing Pet Egg' then
order_by = order_by + 2;
elseif name == 'Magical Pet Egg' then
order_by = order_by + 1;
elseif name == 'Rune Pet Egg' then
order_by = order_by + 0; -- already updated above as the highest prio
else
-- unrecognized, not moving
return -1, -1
end
return bagIndex, order_by;
end
-- swap positions in initial_bag_info[] and initial_position[]
-- for items with final positions p1 and p2
-- This is meant to assign better end positions for the items.
--
-- Note: this function is symmetric, the result of SwapTargetPositions(5, 7) is the same as SwapTargetPositions(7, 5).
-- Note: cannot be called for empty positions.
function SwapTargetPositions(p1, p2)
-- before the swap:
initial_pos_of_item1 = initial_position[p1]
initial_pos_of_item2 = initial_position[p2]
-- check for empty slots:
if initial_bag_info[initial_pos_of_item1] == nil or initial_bag_info[initial_pos_of_item2] == nil then
return; -- no better idea than NOP
end
-- update values after the swap:
initial_bag_info[initial_pos_of_item1]["final_position"] = p2;
initial_bag_info[initial_pos_of_item2]["final_position"] = p1;
initial_position[p1] = initial_pos_of_item2;
initial_position[p2] = initial_pos_of_item1;
end
-- swaps items in bag and updates initial_bag_info[] and initial_position[] accordingly,
-- in such a way that the same actual physical item should be assigned to the same
-- final target location as before the swap;
-- NOTE: if you swap an item to a correct place X then after the swap initial_position[X] = X
-- and initial_bag_info[X]["final_position"] = X.
--
-- Note: this function is symmetric, the result of SwapItemsInBag(5, 7) is the same as SwapItemsInBag(7, 5).
--
-- Neither of the slots can be empty; if you want to move an item to an empty position, use MoveItemInBag(from_pos,to_empty_pos).
function SwapItemsInBag(p1, p2)
-- initial indexes: just a check
if initial_bag_info[p1] == nil or initial_bag_info[p2] == nil then
return;
end
-- swap items
PickupBagItem(GetBagItemInfo(p1)) -- pick up item in bag slot p1 (slot p1 now in cursor)
PickupBagItem(GetBagItemInfo(p2)) -- swap with item in bag slot p2 (slot p2 now in cursor)
PickupBagItem(GetBagItemInfo(p1)) -- put down item p2 into bag slot p1 (cursor empty)
-- update source_position<->target_position accordingly:
-- before: item which was in p1 was assigned to go to target slot t1; p2 was to go to t2;
t1 = initial_bag_info[p1]["final_position"];
t2 = initial_bag_info[p2]["final_position"];
-- after the actual swap in bag, the initial positions should be updated so that the same
-- actual item was assigned to the particular target location:
initial_position[t1] = p2;
initial_position[t2] = p1;
initial_bag_info[p1]["final_position"] = t2;
initial_bag_info[p2]["final_position"] = t1;
end
-- Equivalent of SwapItemsInBag() in the case the second position is empty.
--
-- Note: this function is NOT symmetric, the first slot cannot be empty, the second has to be empty.
function MoveItemInBag(from_item_pos, to_empty_pos)
-- initial indexes: just a check
if initial_bag_info[from_item_pos] == nil or initial_bag_info[to_empty_pos] ~= nil then
return;
end
-- swap items
PickupBagItem(GetBagItemInfo(from_item_pos)); -- pick up item in bag slot from_item_pos (slot from_item_pos now in cursor)
PickupBagItem(GetBagItemInfo(to_empty_pos)); -- put down item from_item_pos into empty bag slot to_empty_pos (cursor empty)
-- update source_position<->target_position accordingly:
-- before: item which was in from_item_pos was assigned to go to target slot t1; to_empty_pos was empty
t1 = initial_bag_info[from_item_pos]["final_position"];
-- after the actual swap in bag, the initial positions should be updated so that the same
-- actual item was assigned to the particular target location:
initial_position[t1] = to_empty_pos;
-- NOTE: if we want to debug properly, then all fields need to be filled in;
-- if you don't want to debug the data after the move is finished, all lines from here till the end of
-- this function can be removed:
i = {};
i.final_position = t1;
i.order_by = initial_bag_info[from_item_pos]["order_by"];
initial_bag_info[to_empty_pos] = i;
initial_bag_info[from_item_pos]=nil;
end
----------------
--- START OF ACTUAL CODE
----------------
----------------
-- 1. loop over bag; for each item store bag_index, order_by;
-- initially set final_position == initial_position
----------------
for b = FIRST_SLOT_TO_SORT, LAST_SLOT_TO_SORT do
bag_index, order_by = GetBagItemOrderBy(b);
if bag_index ~= nil then
-- not empty slot; store info, including order_by == -1 which blocks location of the item
i = {};
i.bag_index = bag_index; -- does it make sense to cache bag_index? it is clearer in the code not to...
i.order_by = order_by;
i.final_position = b;
initial_bag_info[b] = i;
initial_position[b] = b;
end
end
----------------
-- 2. prepare sorting info
-- loop over bag; for each item loop backwards over previous items;
-- if our item should be before the tested item, call SwapTargetPositions(p1, p2)
----------------
for b = FIRST_SLOT_TO_SORT, LAST_SLOT_TO_SORT do
if initial_bag_info[b] ~= nil then
if initial_bag_info[b]["order_by"] ~= -1 then
-- not empty slot and not a blocked item
current_position_of_item_being_moved = b
for a = b - 1, FIRST_SLOT_TO_SORT, -1 do
if initial_position[a] == nil then
-- assign our item to be moved this empty slot
-- before the swap:
initial_pos_of_our_item = initial_position[current_position_of_item_being_moved]
-- update values after the swap:
initial_bag_info[initial_pos_of_our_item]["final_position"] = a;
initial_position[a] = initial_pos_of_our_item;
initial_position[current_position_of_item_being_moved] = nil;
current_position_of_item_being_moved = a;
elseif initial_bag_info[initial_position[a]]["order_by"] ~= -1 then
ini_moved = initial_position[current_position_of_item_being_moved]
ini_checked = initial_position[a]
o_by_moved = initial_bag_info[ini_moved]["order_by"]
o_by_checked = initial_bag_info[ini_checked]["order_by"]
if o_by_moved < o_by_checked then
-- if initial_bag_info[initial_position[current_position_of_item_being_moved]]["order_by"] < initial_bag_info[initial_position[a]]["order_by"] then
SwapTargetPositions(current_position_of_item_being_moved, a);
current_position_of_item_being_moved = a;
else
-- position is correct
break;
end
end
end
end
end
end
----------------
-- 3. perform actual sorting
-- loop over bag from position 1 onwards; move correct item to this position
----------------
for b = FIRST_SLOT_TO_SORT, LAST_SLOT_TO_SORT do
take_item_from = initial_position[b]
if take_item_from ~= nil and take_item_from ~= b then
if initial_bag_info[b] == nil then
MoveItemInBag(take_item_from, b)
else
SwapItemsInBag(take_item_from, b)
end
end
end
|

This post has been edited 1 times, last edit by "Uure" (Jan 20th 2015, 8:07pm)
(To forum admins: I wish you could make it easy to love you...)

|
|
Source code |
1 2 3 4 5 6 7 8 9 10 11 12 |
-- NOTE: initial_bag_info contains additional info (order_by, descr, maybe bag index etc.). -- But if we look just at positions, the above two variables provide reversed mappings. -- The following should always be true for indexes corresponding to not-empty bag slots: -- initial_bag_info[initial_position[X]]["final_position"] == X -- initial_position[initial_bag_info[X]["final_position"]] == X -- (note that initial_position is a plain "array", while initial_bag_info has multiple elements and you have to access "final_position" member in the above formulas. -- If a particular location X is empty, then initial_bag_info[X] == nil; there will also be some indexes missing from the keys of initial_position[] -- (but hard to say which), and the value set of initial_position[] will not contain X -- If a particular location X contains an item which should not be moved, then GetBagItemOrderBy(index) should return (-1, -1). For such index, simply: -- initial_bag_info[X]["final_location"] = X and initial_position[X] = X. |

The only issue I have is that after sorting several items the macro stops. If it stops after picking an item and before putting it back, you end up with an item attached to your mouse (SO BE CAREFUL!!!!). Re-running the macro sorts next items and after re-running it a few times the whole bag is sorted.
)|
|
Source code |
1 2 3 4 5 |
local bagIndex, icon, name, itemCount, locked, itemQuality = GetBagItemInfo(index);
if icon == nil or name == "" then
-- empty
return nil;
end
|

This post has been edited 3 times, last edit by "Uure" (Jan 20th 2015, 11:28pm)
The only issue I have is that after sorting several items the macro stops. If it stops after picking an item and before putting it back, you end up with an item attached to your mouse (SO BE CAREFUL!!!!).
|
|
Source code |
1 2 3 4 5 6 7 |
-- sometimes an egg stays picked up: let's put it back to bags info = GetCursorItemInfo() tpe = CursorItemType() -- if tpe == "bag" then info contains bag index of where the item was picked up from if (tpe == "bag") then PickupBagItem(info); end |
