• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver

Snippet - Enhanced Sub PetToys for KA12

Ladon

Birthplace: Grobb
Creator
Joined
Oct 17, 2012
RedCents
5,836¢
shanecol had a post earlier this year for how to modify KA11 to speed up the PetToys routine. I've modified that for KA12 to incorporate his speedup AND allow for passing out more than two items per pettoys#=.

This should be pasted over everything from
| SUB: Check PetToys - Based on code from el_nene's autobot. Used with permission.
to
| SUB: Check Plugin

My 110 Mage INI's Pet Toys section looks like this:

Code:
PetToysOn=1
PetToysSize=4
PetToys1=Grant Wirn's Armaments|Summoned: Gorstruck Fireblade|Summoned: Gorstruck Fireblade
PetToys2=Grant Ioulin's Heirlooms|Arcronite Linked Bracelet|Arcronite Jade Bracelet|Arcronite Gold Ring|Arcronite Ridged Earhoop|Arcronite Satin Choker|Arcronite Woven Shawl
PetToys3=Grant Wirn's Plate|Magmaforged Plate Breastplate|Magmaforged Plate Helm|Magmaforged Plate Vambraces|Magmaforged Plate Greaves|Magmaforged Plate Boots|Magmaforged Plate Gauntlets|Magmaforged Plate Bracers|Summoned: Magmaforged Belt
PetToys4=Grant Visor of Gobeker|Summoned: Visor of Gobeker

Code:
| SUB: Check PetToys - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
    Sub PetToys(string petName)
        /if (!${Me.Pet.ID}) /return w
        DEBUGPET PetToys Enter
        /declare i            int    local
        /declare j            int    local
        /declare GiveCnt      int    local 0
        /declare GrabItem     int    local 0
        /declare PetToySpell  string local 0
        /declare FullText     string local
        /declare 2ndPart      string local
        /declare 3rdPart      string local
        /declare 4thPart      string local
        /declare 5thPart      string local
        /declare 6thPart      string local
        /declare 7thPart      string local
        /declare 8thPart      string local
        /declare 9thPart      string local
        /declare PetToysTemp  string local ${Ini[${IniFileName},Pet,PetToysGave]}
        /declare GaveItem     int    local 1
        /declare CondNo       int    local 0
        /call OpenInvSlot
        /declare petID int local ${Spawn[pet ${petName}].ID}
        /if (!${Defined[PetToysOn]}) /return
        /if (!${PetToysOn}) /return 0
        /if (${BagNum}==0) {
            /echo You must have an empty Top Inventory slot for Pet Toys to work.
            /varset PetToysOn 0
            /return X
        }
        /if (!${InvSlot[pack${BagNum}].Item.Container} && !${Me.FreeInventory}) {
            /echo Inventory is full
            /varset PetToysOn 0
            /return X
        }
        | reset if different pet name only on my pet
        /if (!${PetToysTemp.Find[${petName}]} && ${Me.Pet.CleanName.Equal[${petName}]}) {
            /ini "${IniFileName}" "Pet" "PetToysGave" "0"
            /varset PetToysTemp 0
        }
        /for i 1 to ${PetToys.Size}
            DEBUGPET CHECKING: ${PetToys[${i}]}
            /if (${ConOn} && ${PetToys[${i}].Find[|cond]}) {
                /varset CondNo ${PetToys[${i}].Mid[${Math.Calc[${PetToys[${i}].Find[|cond]}+5]},3]}
            } else {
                /varset CondNo 0
            }
          
            /if (${DebugPet}) {
                /echo \atPetDebug PetToys 1: ${PetToys[${i}]}
                /echo \atPetDebug PetToys 2: ${PetToysTemp}
                /echo \atPetDebug PetToys 3: ${PetToys[${i}].Equal[Null]} || ${PetToysTemp.Find[${petName}]} && ${PetToysTemp.Find[${PetToys[${i}]}]}
                /echo \atPetDebug PetToys 4: ${If[CondNo,${Cond[${CondNo}]},0]}
            }
            /if (${CondNo}) {
                /if (${If[${Cond[${CondNo}]},0,1]}) /continue
            }
            | Had to add pet name check else it will always skip giving weapons to OTHER pets.
            DEBUGPET PetToys ${PetToys[${i}].Equal[Null]} || (${Me.Pet.CleanName.Equal[${petName}]} && ${PetToysTemp.Find[${petName}]} && ${PetToysTemp.Find[${PetToys[${i}]}]}) SkipPetToy 1
            /if (${PetToys[${i}].Equal[Null]} || (${Me.Pet.CleanName.Equal[${petName}]} && ${PetToysTemp.Find[${petName}]} && ${PetToysTemp.Find[${PetToys[${i}]}]})) /continue
            | Are we handing weapons to the pet
            /if (${PetToys[${i}].Arg[2,|].Length} && ${PetToys[${i}].Arg[2,|].NotEqual[null]}) {
                /varset FullText ${PetToys[${i}]}
                /varset PetToySpell ${PetToys[${i}].Arg[1,|]}
                /varset 2ndPart ${PetToys[${i}].Arg[2,|]}
                /varset 3rdPart ${PetToys[${i}].Arg[3,|]}
                /varset 4thPart ${PetToys[${i}].Arg[4,|]}
                /varset 5thPart ${PetToys[${i}].Arg[5,|]}
                /varset 6thPart ${PetToys[${i}].Arg[6,|]}
                /varset 7thPart ${PetToys[${i}].Arg[7,|]}
                /varset 8thPart ${PetToys[${i}].Arg[8,|]}
                /varset 9thPart ${PetToys[${i}].Arg[9,|]}
            } else {
                /varset FullText
                /varset PetToySpell ${PetToys[${i}]}
                /varset 2ndPart
                /varset 3rdPart
                /varset 4thPart
                /varset 5thPart
                /varset 6thPart
                /varset 7thPart
                /varset 8thPart
                /varset 9thPart
            }
            /varset GiveCnt 0
            DEBUGPET PetToys ${Me.Pet.CleanName.Equal[${petName}]} && ${2ndPart.Length} && ${PetToysTemp.Find[1]} && ${PetToysTemp.Find[2]} SkipPetToy 2
            /if (${Me.Pet.CleanName.Equal[${petName}]} && ${2ndPart.Length} && ${PetToysTemp.Find[1]} && ${PetToysTemp.Find[2]}) /continue
            | Check if spell level less than 76 because mage pets auto equipped after that.
            /if (${Me.Pet.CleanName.Equal[${petName}]} && ${Spell[${PetToySpell}].Level}>=76 && (${PetToySpell.Find[Plate]} || ${PetToySpell.Find[Muzzle]} || ${PetToySpell.Find[Visor]} || ${PetToySpell.Find[Belt]})) /continue
            | Check for pet toy spells in book to prevent double casting of items
            /if (${Me.Book[${PetToySpell}]}) {
                /call CastWhat "${PetToySpell}" ${Me.ID} Pet-nomem 0
                /if (!${PetToysTemp.Find[${petName}]} && ${Me.Pet.CleanName.Equal[${petName}]}) {
                    /ini "${IniFileName}" "Pet" "PetToysGave" "${petName}"
                    /varset PetToysTemp ${Ini[${IniFileName},Pet,PetToysGave]}
                }
                /if (${Macro.Return.Equal[CAST_SUCCESS]}) {
                    /echo Casting pet toy spell >> ${PetToySpell} <<
                }
                /delay 15s ${Cursor.ID}
                /if (!${Cursor.ID}) /return 0
                | Check if spell has summoned a bag or folded pack
                /if (${Cursor.Container} || ${Cursor.Name.Find[Folded]}) {
                    | If item is in Inv Slot exchange it with bag on cursor
                    /if (${InvSlot[pack${i}].Item.ID}) /nomodkey /itemnotify pack${BagNum} leftmouseup
                    /while (1) {
                        /delay 2s ${Cursor.ID}
                        | Drop bag or item into inventory
                        /autoinventory
                        /delay 1s
                        | Drop exchanged item into inventory after bag is dropped
                        /if (${Cursor.ID}) /autoinventory
                        | If folded pack right click to convert to phantom satchel
                        /if (${InvSlot[pack${BagNum}].Item.Name.Find[folded]}) {
                            /nomodkey /itemnotify pack${BagNum} rightmouseup
                            /echo Opening ${InvSlot[pack${BagNum}].Item.Name}
                            /delay 3s
                        } else {
                            /break
                        }
                    }
                }
                /if (${InvSlot[pack${BagNum}].Item.Container} && (${InvSlot[pack${BagNum}].Item.Name.Find[Phantom Satchel]} || ${InvSlot[pack${BagNum}].Item.Name.Find[Pouch of Quellious]})) {
                    | Open the bag
                    /nomodkey /itemnotify pack${BagNum} rightmouseup
                    /delay 10
                    DEBUGPET PetToys ${i} ${PetToySpell} ${2ndPart} ${3rdPart}
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${2ndPart}1]}) && ${2ndPart.Length} && ${FindItemCount[=${2ndPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${2ndPart.Length} && ${FindItemCount[=${2ndPart}]})) {
                        /call GiveTo "${2ndPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${2ndPart}1
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${3rdPart}2]}) && ${3rdPart.Length} && ${FindItemCount[=${3rdPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${3rdPart.Length} && ${FindItemCount[=${3rdPart}]})) {
                        /call GiveTo "${3rdPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${3rdPart}2
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${4thPart}2]}) && ${4thPart.Length} && ${FindItemCount[=${4thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${4thPart.Length} && ${FindItemCount[=${4thPart}]})) {
                        /call GiveTo "${4thPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${4thPart}2
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${5thPart}2]}) && ${5thPart.Length} && ${FindItemCount[=${5thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${5thPart.Length} && ${FindItemCount[=${5thPart}]})) {
                        /call GiveTo "${5thPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${5thPart}2
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    /if (${GiveCnt}>=4) {
                    /call PressGive
                    /varset GiveCnt 0
                    }
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${6thPart}2]}) && ${6thPart.Length} && ${FindItemCount[=${6thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${6thPart.Length} && ${FindItemCount[=${6thPart}]})) {
                        /call GiveTo "${6thPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${6thPart}2
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${7thPart}2]}) && ${7thPart.Length} && ${FindItemCount[=${7thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${7thPart.Length} && ${FindItemCount[=${7thPart}]})) {
                        /call GiveTo "${7thPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${7thPart}2
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${8thPart}2]}) && ${8thPart.Length} && ${FindItemCount[=${8thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${8thPart.Length} && ${FindItemCount[=${8thPart}]})) {
                        /call GiveTo "${8thPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${8thPart}2
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    | Condition revised to allow for pet weapons to be given to other people's pets.
                    /if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${9thPart}2]}) && ${9thPart.Length} && ${FindItemCount[=${9thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${9thPart.Length} && ${FindItemCount[=${9thPart}]})) {
                        /call GiveTo "${9thPart}" ${petID}
                        /varcalc GiveCnt ${GiveCnt}+1
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${9thPart}2
                        /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    }
                    /if (${GiveCnt}>=4) {
                    /call PressGive
                    /varset GiveCnt 0
                    }
                    /if (!${2ndPart.Length}) {
                        /for j 0 to ${InvSlot[pack${BagNum}].Item.Container}
                            /if (${InvSlot[pack${BagNum}].Item.Item[${j}].ID} && ${InvSlot[pack${BagNum}].Item.Item[${j}].Name.Length}) {
                                /call GiveTo "${InvSlot[pack${BagNum}].Item.Item[${j}].Name}" ${petID}
                                /varcalc GiveCnt ${GiveCnt}+1
                                }
                    /if (${GiveCnt}>=4) {
                    /call PressGive
                    /varset GiveCnt 0
                    }
                        /next j
                        /if (${j}>=8 && !${PetToysTemp.Find[${PetToySpell}]} && ${Me.Pet.CleanName.Equal[${petName}]}) {
                            /varset PetToysTemp ${PetToysTemp}|${PetToySpell}
                            /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                        }
                    }
                }
                /if (${Cursor.Name.Find[Summoned:]}) {
                    /if (${2ndPart.Length} && !${PetToysTemp.Find[1]}) {
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${2ndPart}1
                    } else /if (${2ndPart.Length} && ${PetToysTemp.Find[1]} ) {
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${2ndPart}2
                    } else /if (!${2ndPart.Length} && !${PetToysTemp.Find[${PetToySpell}]}) {
                        /varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${Cursor.Name}
                    }
                    /call GiveTo "${Cursor.Name}" ${petID}
                    /varcalc GiveCnt ${GiveCnt}+1
                    /if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
                    /varset GaveItem 0
                }
                    /call PressGive
                /if (${InvSlot[pack${BagNum}].Item.Name.Find[Phantom Satchel]} || ${InvSlot[pack${BagNum}].Item.Name.Find[Pouch of Quellious]}) /call DestroyBag
            }
        /next i
        | MUST reset PetToysGave after cycle complete in order to stop calling PetToys all the time.
        /varset PetToysGave ${PetToysTemp}
        /if (${Window[InventoryWindow].Open} && !${GaveItem}) /keypress inventory
        /varset PetToysDone 1
        /call DoWeMove 1 PetToys
        DEBUGPET PetToys Leave
    /return
| ----------------------------------------------------------------------------
| SUB: Check OpenInvSlot - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
    Sub OpenInvSlot
        DEBUGBUFF OpenInvSlot Enter
        /if (${BagNum}) /return
        /declare i int local
        /varset BagNum 0
        /for i 1 to 10
            /if (${InvSlot[pack${i}].Item.Container}) /continue
            /if (!${InvSlot[pack${i}].Item.Container} || ${InvSlot[pack${i}].Item.ID}==0) {
                | Must have at least 2 inv slots open in order to swap bags and items
                /if (${Me.FreeInventory}>=2) /varset BagNum ${i}
            }
            /if (${BagNum}) {
                /echo Pet Toys: Inventory slot ${i} is empty using that one.
                /delay .5
                /return
            }
        /next i
        DEBUGBUFF OpenInvSlot Leave
    /return
| ----------------------------------------------------------------------------
| SUB: Check DestroyBag - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
    Sub DestroyBag
        DEBUGBUFF DestroyBag Enter
        /declare j int local
        | Make sure bag has no items other than summoned in it before deleting.
        /if (${InvSlot[pack${BagNum}].Item.Items}) {
            /for j 0 to ${InvSlot[pack${BagNum}].Item.Container}
                /if (!${InvSlot[pack${BagNum}].Item.Item[${j}].NoRent} && ${InvSlot[pack${BagNum}].Item.Item[${j}].Name.Length}) {
                    /echo Bag has non summoned item(s) in it. Aborting delete. Pet Toys Off
                    /varset PetToysOn 0
                    /return
                }
            /next j
        }
        /if (${InvSlot[pack${BagNum}].Item.Name.Find[Phantom Satchel]} || ${InvSlot[pack${BagNum}].Item.Name.Find[Pouch of Quellious]}) {
            /nomodkey /itemnotify pack${BagNum} leftmouseup
            /delay 5s ${Cursor.ID}
            /if (${Cursor.Name.Find[Phantom Satchel]} || ${Cursor.Name.Find[Pouch of Quellious]}) /destroy
            /delay 20 !${Cursor.ID}
        }
        DEBUGBUFF Leave
    /return
| ----------------------------------------------------------------------------
| SUB: Check GiveTo - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
    Sub GiveTo(string GItem, int GTarget)
        DEBUGBUFF GiveTo Enter
        /declare ItemSummoned int local 0
        /if (${Target.ID}!=${GTarget}) {
            /target id ${GTarget}
            /delay 2s ${Target.ID}==${GTarget}
        }
        /if (${Target.Distance}>5 && ${Target.Distance}<=${CampRadius}) {
            /moveto id ${Target.ID} mdist 5
            /delay 50 ${MoveTo.Stopped}
        }
        /if (${Me.Mount.ID}) {
            /dismount
            /delay 20 !${Me.Mount.ID}
        }
        /if (${Me.Levitating}) {
            /removelev
            /delay 20 !${Me.Levitating}
        }
        /while (!${Cursor.ID} && ${FindItemCount[=${GItem}]}>0) {
            /shift /itemnotify "${GItem}" leftmouseup
            /delay 20 ${Cursor.ID}
        }
        /while (${Cursor.ID} && ${Cursor.NoRent}) {
            /if (${Cursor.ID}==${FindItem[=${GItem}].ID}) {
                /varset ItemSummoned 1
                /nomodkey /click left target
            }
            /delay 2
        }
        DEBUGBUFF GiveTo Leave
/return
| ----------------------------------------------------------------------------
| SUB: PressGive
| ----------------------------------------------------------------------------
        Sub PressGive()
        /delay 30 ${Window[GiveWnd].Open}
        /if (${Window[GiveWnd].Open}) {
            /notify GiveWnd GVW_Give_Button leftmouseup
        }
        /delay 15
        | New pet patch gives back item if pet has equipped. Delete item from cursor.
        /if (${Cursor.ID} && (${Cursor.NoRent} || ${Cursor.Name.Find[muzzle]} || ${Cursor.Name.Find[visor]} || ${Cursor.Name.Find[belt]})) {
            /while (${Cursor.ID}) {
                /destroy
                /delay 10
            }
        }
        /delay 200 !${Window[GiveWnd].Open}
    /return
| ----------------------------------------------------------------------------
| SUB: Check Plugin
 
I just tried this myself for my 115 mag and pet toys is much faster! please incorporate this into KA 12. It easily cuts the pet toy process down by atleast 50%. Super awesome! Just for kicks I timed it and it was about 55 seconds per pet with full sets of everything they can take.

My 115 mag pet toys list for KA:
PetToysOn=1
PetToysSize=4
PetToys1=Grant Yalrek's Armaments|Summoned: Silver Shortsword|Summoned: Silver Fireblade
PetToys2=Grant Visor of Shoen
PetToys3=Grant Ocoenydd's Plate
PetToys4=Grant Crystasia's Heirlooms
 
Last edited:
Funny I was looking at ways to improve my mage pets, ended up saying piss on it. Just setup the weapons and hand everything out manually. Nothing better then telling the person your grouped with “hang on mage being stupid” while spamming sorry I don’t need this.
 
There's a typo in the posted sub replacement, on line 56, where it reads:
Code:
/echo \atPetDebug PetToys 4: ${If[CondNo,${Cond[${CondNo}]},0]}
and should read:
Code:
/echo \atPetDebug PetToys 4: ${If[${CondNo},${Cond[${CondNo}]},0]}

This code not only greatly increases the speed of the pet gearing, but it expands functionality, and fixes a bug in the current live release (as of 01/06/21) where the code is currently only summoning 1 item for pets in many cases
 
Too many brackets, thank you for finding that. I used mercilessly troll RedGuides users after issuing a /pettoysplz group but now everybody's ready before I'm even done judging thread titles.
 
I am having a strange issue where my mage runs off to a location using mq2nav every time he gives the last item to a pet. I turned on debug, and it shows the following. Any idea what the cause could be?

NavBug.PNG
 
I am having a strange issue where my mage runs off to a location using mq2nav every time he gives the last item to a pet. I turned on debug, and it shows the following. Any idea what the cause could be?

View attachment 27249

I have seen this too but not with @Ladon code. I've seen it in the existing 12.001 code. I've had it kill my mage who ran off into kos mobs after equipping a pet just like you said.
 
@yangwenlii That is the mage returning to their camp location. Before the mage starts to give toys they move to the pet and drop their mount and Levi, to get close to the pet. When finished giving the toys to the pet. The mage returns back to their camp location.
 
I've had half a dozen deaths in the last month and a half, which I hadn't chased down yet for cause. Hadn't even pegged it to pet toy interaction, as the mage runs in the background, and it's been happening during/between combats as I wander mob to mob. Since I haven't been camping, I'm just wandering the arena in Kael, I'm not sure what "camp" they're returning to, but they do go running off across the zone and dying every so often.
 
OK I am going to change the /call to DoWeMove to only forcetocamp when you have ReturnToCamp turned on. The only other choice is to ignore calling the DoWeMove at all, but then you will have to manually move your mage around in camp after giving Pet toys.
 
alternatively we could set camp just prior to moving to hand out toys, then unset it? seems prone to issues too though.

or, if we have returntocamp set then call dowemove, but if returntocamp isn't set then call dowechase
 
That change will be greatly appreciated because I spent so much time tracking down why the hell my mage would run across the map when chaseme was on!
 
@ctaylor22 Knowing that this is the cause has helped me find a temporary solution. Thanks. Since the mage is running to the last set camp location even if camphere is set to off, a I've set my pettoysplz hotkey so that it turns /camphere on and then back off before /pettoysplz, and the mage is behaving now.
 
I find myself back at this post each update looking for a pet toy fix when my mages stop giving weapons to a pet. Is the 12.0 version attempting to do something different with the code or has something changed? Using this code for now. Thanks.
[CODE lang="ini" title="Check PetToys"]| ----------------------------------------------------------------------------
| SUB: Check PetToys - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
Sub PetToys(string petName)
/if (!${Me.Pet.ID}) /return w
DEBUGPET PetToys Enter
/declare i int local
/declare j int local
/declare GiveCnt int local 0
/declare GrabItem int local 0
/declare PetToySpell string local 0
/declare FullText string local
/declare 2ndPart string local
/declare 3rdPart string local
/declare 4thPart string local
/declare 5thPart string local
/declare 6thPart string local
/declare 7thPart string local
/declare 8thPart string local
/declare 9thPart string local
/declare PetToysTemp string local ${Ini[${IniFileName},Pet,PetToysGave]}
/declare GaveItem int local 1
/declare CondNo int local 0
/call OpenInvSlot
/declare petID int local ${Spawn[pet ${petName}].ID}
/if (!${Defined[PetToysOn]}) /return
/if (!${PetToysOn}) /return 0
/if (${BagNum}==0) {
/echo You must have an empty Top Inventory slot for Pet Toys to work.
/varset PetToysOn 0
/return X
}
/if (!${InvSlot[pack${BagNum}].Item.Container} && !${Me.FreeInventory}) {
/echo Inventory is full
/varset PetToysOn 0
/return X
}
| reset if different pet name only on my pet
/if (!${PetToysTemp.Find[${petName}]} && ${Me.Pet.CleanName.Equal[${petName}]}) {
/ini "${IniFileName}" "Pet" "PetToysGave" "0"
/varset PetToysTemp 0
}
/for i 1 to ${PetToys.Size}
DEBUGPET CHECKING: ${PetToys[${i}]}
/if (${ConOn} && ${PetToys[${i}].Find[|cond]}) {
/varset CondNo ${PetToys[${i}].Mid[${Math.Calc[${PetToys[${i}].Find[|cond]}+5]},3]}
} else {
/varset CondNo 0
}

/if (${DebugPet}) {
/echo \atPetDebug PetToys 1: ${PetToys[${i}]}
/echo \atPetDebug PetToys 2: ${PetToysTemp}
/echo \atPetDebug PetToys 3: ${PetToys[${i}].Equal[Null]} || ${PetToysTemp.Find[${petName}]} && ${PetToysTemp.Find[${PetToys[${i}]}]}
/echo \atPetDebug PetToys 4: ${If[${CondNo},${Cond[${CondNo}]},0]}
}
/if (${CondNo}) {
/if (${If[${Cond[${CondNo}]},0,1]}) /continue
}
| Had to add pet name check else it will always skip giving weapons to OTHER pets.
DEBUGPET PetToys ${PetToys[${i}].Equal[Null]} || (${Me.Pet.CleanName.Equal[${petName}]} && ${PetToysTemp.Find[${petName}]} && ${PetToysTemp.Find[${PetToys[${i}]}]}) SkipPetToy 1
/if (${PetToys[${i}].Equal[Null]} || (${Me.Pet.CleanName.Equal[${petName}]} && ${PetToysTemp.Find[${petName}]} && ${PetToysTemp.Find[${PetToys[${i}]}]})) /continue
| Are we handing weapons to the pet
/if (${PetToys[${i}].Arg[2,|].Length} && ${PetToys[${i}].Arg[2,|].NotEqual[null]}) {
/varset FullText ${PetToys[${i}]}
/varset PetToySpell ${PetToys[${i}].Arg[1,|]}
/varset 2ndPart ${PetToys[${i}].Arg[2,|]}
/varset 3rdPart ${PetToys[${i}].Arg[3,|]}
/varset 4thPart ${PetToys[${i}].Arg[4,|]}
/varset 5thPart ${PetToys[${i}].Arg[5,|]}
/varset 6thPart ${PetToys[${i}].Arg[6,|]}
/varset 7thPart ${PetToys[${i}].Arg[7,|]}
/varset 8thPart ${PetToys[${i}].Arg[8,|]}
/varset 9thPart ${PetToys[${i}].Arg[9,|]}
} else {
/varset FullText
/varset PetToySpell ${PetToys[${i}]}
/varset 2ndPart
/varset 3rdPart
/varset 4thPart
/varset 5thPart
/varset 6thPart
/varset 7thPart
/varset 8thPart
/varset 9thPart
}
/varset GiveCnt 0
DEBUGPET PetToys ${Me.Pet.CleanName.Equal[${petName}]} && ${2ndPart.Length} && ${PetToysTemp.Find[1]} && ${PetToysTemp.Find[2]} SkipPetToy 2
/if (${Me.Pet.CleanName.Equal[${petName}]} && ${2ndPart.Length} && ${PetToysTemp.Find[1]} && ${PetToysTemp.Find[2]}) /continue
| Check if spell level less than 76 because mage pets auto equipped after that.
/if (${Me.Pet.CleanName.Equal[${petName}]} && ${Spell[${PetToySpell}].Level}>=76 && (${PetToySpell.Find[Plate]} || ${PetToySpell.Find[Muzzle]} || ${PetToySpell.Find[Visor]} || ${PetToySpell.Find[Belt]})) /continue
| Check for pet toy spells in book to prevent double casting of items
/if (${Me.Book[${PetToySpell}]}) {
/call CastWhat "${PetToySpell}" ${Me.ID} Pet-nomem 0
/if (!${PetToysTemp.Find[${petName}]} && ${Me.Pet.CleanName.Equal[${petName}]}) {
/ini "${IniFileName}" "Pet" "PetToysGave" "${petName}"
/varset PetToysTemp ${Ini[${IniFileName},Pet,PetToysGave]}
}
/if (${Macro.Return.Equal[CAST_SUCCESS]}) {
/echo Casting pet toy spell >> ${PetToySpell} <<
}
/delay 15s ${Cursor.ID}
/if (!${Cursor.ID}) /return 0
| Check if spell has summoned a bag or folded pack
/if (${Cursor.Container} || ${Cursor.Name.Find[Folded]}) {
| If item is in Inv Slot exchange it with bag on cursor
/if (${InvSlot[pack${i}].Item.ID}) /nomodkey /itemnotify pack${BagNum} leftmouseup
/while (1) {
/delay 2s ${Cursor.ID}
| Drop bag or item into inventory
/autoinventory
/delay 1s
| Drop exchanged item into inventory after bag is dropped
/if (${Cursor.ID}) /autoinventory
| If folded pack right click to convert to phantom satchel
/if (${InvSlot[pack${BagNum}].Item.Name.Find[folded]}) {
/nomodkey /itemnotify pack${BagNum} rightmouseup
/echo Opening ${InvSlot[pack${BagNum}].Item.Name}
/delay 3s
} else {
/break
}
}
}
/if (${InvSlot[pack${BagNum}].Item.Container} && (${InvSlot[pack${BagNum}].Item.Name.Find[Phantom Satchel]} || ${InvSlot[pack${BagNum}].Item.Name.Find[Pouch of Quellious]})) {
| Open the bag
/nomodkey /itemnotify pack${BagNum} rightmouseup
/delay 10
DEBUGPET PetToys ${i} ${PetToySpell} ${2ndPart} ${3rdPart}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${2ndPart}1]}) && ${2ndPart.Length} && ${FindItemCount[=${2ndPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${2ndPart.Length} && ${FindItemCount[=${2ndPart}]})) {
/call GiveTo "${2ndPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${2ndPart}1
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${3rdPart}2]}) && ${3rdPart.Length} && ${FindItemCount[=${3rdPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${3rdPart.Length} && ${FindItemCount[=${3rdPart}]})) {
/call GiveTo "${3rdPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${3rdPart}2
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${4thPart}2]}) && ${4thPart.Length} && ${FindItemCount[=${4thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${4thPart.Length} && ${FindItemCount[=${4thPart}]})) {
/call GiveTo "${4thPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${4thPart}2
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${5thPart}2]}) && ${5thPart.Length} && ${FindItemCount[=${5thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${5thPart.Length} && ${FindItemCount[=${5thPart}]})) {
/call GiveTo "${5thPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${5thPart}2
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
/if (${GiveCnt}>=4) {
/call PressGive
/varset GiveCnt 0
}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${6thPart}2]}) && ${6thPart.Length} && ${FindItemCount[=${6thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${6thPart.Length} && ${FindItemCount[=${6thPart}]})) {
/call GiveTo "${6thPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${6thPart}2
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${7thPart}2]}) && ${7thPart.Length} && ${FindItemCount[=${7thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${7thPart.Length} && ${FindItemCount[=${7thPart}]})) {
/call GiveTo "${7thPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${7thPart}2
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${8thPart}2]}) && ${8thPart.Length} && ${FindItemCount[=${8thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${8thPart.Length} && ${FindItemCount[=${8thPart}]})) {
/call GiveTo "${8thPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${8thPart}2
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
| Condition revised to allow for pet weapons to be given to other people's pets.
/if (((${Me.Pet.CleanName.Equal[${petName}]} && !${PetToysTemp.Find[${9thPart}2]}) && ${9thPart.Length} && ${FindItemCount[=${9thPart}]}) || (!${Me.Pet.CleanName.Equal[${petName}]} && ${9thPart.Length} && ${FindItemCount[=${9thPart}]})) {
/call GiveTo "${9thPart}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${9thPart}2
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
/if (${GiveCnt}>=4) {
/call PressGive
/varset GiveCnt 0
}
/if (!${2ndPart.Length}) {
/for j 0 to ${InvSlot[pack${BagNum}].Item.Container}
/if (${InvSlot[pack${BagNum}].Item.Item[${j}].ID} && ${InvSlot[pack${BagNum}].Item.Item[${j}].Name.Length}) {
/call GiveTo "${InvSlot[pack${BagNum}].Item.Item[${j}].Name}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
}
/if (${GiveCnt}>=4) {
/call PressGive
/varset GiveCnt 0
}
/next j
/if (${j}>=8 && !${PetToysTemp.Find[${PetToySpell}]} && ${Me.Pet.CleanName.Equal[${petName}]}) {
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}
/ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
}
}
}
/if (${Cursor.Name.Find[Summoned:]}) {
/if (${2ndPart.Length} && !${PetToysTemp.Find[1]}) {
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${2ndPart}1
} else /if (${2ndPart.Length} && ${PetToysTemp.Find[1]} ) {
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${2ndPart}2
} else /if (!${2ndPart.Length} && !${PetToysTemp.Find[${PetToySpell}]}) {
/varset PetToysTemp ${PetToysTemp}|${PetToySpell}:${Cursor.Name}
}
/call GiveTo "${Cursor.Name}" ${petID}
/varcalc GiveCnt ${GiveCnt}+1
/if (${Me.Pet.CleanName.Equal[${petName}]}) /ini "${IniFileName}" "Pet" "PetToysGave" "${PetToysTemp}"
/varset GaveItem 0
}
/call PressGive
/if (${InvSlot[pack${BagNum}].Item.Name.Find[Phantom Satchel]} || ${InvSlot[pack${BagNum}].Item.Name.Find[Pouch of Quellious]}) /call DestroyBag
}
/next i
| MUST reset PetToysGave after cycle complete in order to stop calling PetToys all the time.
/varset PetToysGave ${PetToysTemp}
/if (${Window[InventoryWindow].Open} && !${GaveItem}) /keypress inventory
/varset PetToysDone 1
/call DoWeMove 1 PetToys
DEBUGPET PetToys Leave
/return
| ----------------------------------------------------------------------------
| SUB: Check OpenInvSlot - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
Sub OpenInvSlot
DEBUGBUFF OpenInvSlot Enter
/if (${BagNum}) /return
/declare i int local
/varset BagNum 0
/for i 1 to 10
/if (${InvSlot[pack${i}].Item.Container}) /continue
/if (!${InvSlot[pack${i}].Item.Container} || ${InvSlot[pack${i}].Item.ID}==0) {
| Must have at least 2 inv slots open in order to swap bags and items
/if (${Me.FreeInventory}>=2) /varset BagNum ${i}
}
/if (${BagNum}) {
/echo Pet Toys: Inventory slot ${i} is empty using that one.
/delay .5
/return
}
/next i
DEBUGBUFF OpenInvSlot Leave
/return
| ----------------------------------------------------------------------------
| SUB: Check DestroyBag - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
Sub DestroyBag
DEBUGBUFF DestroyBag Enter
/declare j int local
| Make sure bag has no items other than summoned in it before deleting.
/if (${InvSlot[pack${BagNum}].Item.Items}) {
/for j 0 to ${InvSlot[pack${BagNum}].Item.Container}
/if (!${InvSlot[pack${BagNum}].Item.Item[${j}].NoRent} && ${InvSlot[pack${BagNum}].Item.Item[${j}].Name.Length}) {
/echo Bag has non summoned item(s) in it. Aborting delete. Pet Toys Off
/varset PetToysOn 0
/return
}
/next j
}
/if (${InvSlot[pack${BagNum}].Item.Name.Find[Phantom Satchel]} || ${InvSlot[pack${BagNum}].Item.Name.Find[Pouch of Quellious]}) {
/nomodkey /itemnotify pack${BagNum} leftmouseup
/delay 5s ${Cursor.ID}
/if (${Cursor.Name.Find[Phantom Satchel]} || ${Cursor.Name.Find[Pouch of Quellious]}) /destroy
/delay 20 !${Cursor.ID}
}
DEBUGBUFF Leave
/return
| ----------------------------------------------------------------------------
| SUB: Check GiveTo - Based on code from el_nene's autobot. Used with permission.
| Autobot is available at www.Macroquest2.com VIP macro section.
| Updated and Revised for KissAssist
| ----------------------------------------------------------------------------
Sub GiveTo(string GItem, int GTarget)
DEBUGBUFF GiveTo Enter
/declare ItemSummoned int local 0
/if (${Target.ID}!=${GTarget}) {
/target id ${GTarget}
/delay 2s ${Target.ID}==${GTarget}
}
/if (${Target.Distance}>5 && ${Target.Distance}<=${CampRadius}) {
/moveto id ${Target.ID} mdist 5
/delay 50 ${MoveTo.Stopped}
}
/if (${Me.Mount.ID}) {
/dismount
/delay 20 !${Me.Mount.ID}
}
/if (${Me.Levitating}) {
/removelev
/delay 20 !${Me.Levitating}
}
/while (!${Cursor.ID} && ${FindItemCount[=${GItem}]}>0) {
/shift /itemnotify "${GItem}" leftmouseup
/delay 20 ${Cursor.ID}
}
/while (${Cursor.ID} && ${Cursor.NoRent}) {
/if (${Cursor.ID}==${FindItem[=${GItem}].ID}) {
/varset ItemSummoned 1
/nomodkey /click left target
}
/delay 2
}
DEBUGBUFF GiveTo Leave
/return
| ----------------------------------------------------------------------------
| SUB: PressGive
| ----------------------------------------------------------------------------
Sub PressGive()
/delay 30 ${Window[GiveWnd].Open}
/if (${Window[GiveWnd].Open}) {
/notify GiveWnd GVW_Give_Button leftmouseup
}
/delay 15
| New pet patch gives back item if pet has equipped. Delete item from cursor.
/if (${Cursor.ID} && (${Cursor.NoRent} || ${Cursor.Name.Find[muzzle]} || ${Cursor.Name.Find[visor]} || ${Cursor.Name.Find[belt]})) {
/while (${Cursor.ID}) {
/destroy
/delay 10
}
}
/delay 200 !${Window[GiveWnd].Open}
/return
| ----------------------------------------------------------------------------
| SUB: Check Plugin
| ----------------------------------------------------------------------------[/CODE]
 
Last edited:
I may be missing something, being new here, but the toys sub seems off. AFAIK mage and non-mage pets are being given the same gear whether they can use it or not. At 100+ (I cant remember exact level, besides point though) mage pets only accept 2 weapons and 4 of the heirlooms. I tank with my mage, so I almost always equip rageswords with the 4 heirlooms it accepts. If i want to equip other pet wielders in my group, they just get the same gear, even though its not appropriate for their role. I equip non-mage pets with a combo of dps swords, the new visor, oc's plate armor, and then cryst heirlooms (the bracer is rejected after the plate is given). Perhaps a simple(?) solution would be ini for mages and then for non-mage equipment.
 
Last edited:
There hasn't been a version able to distict between the different type of pets. But this sub handles tools much faster than original kissassist. So using this mod, the handout of all the stuff is so fast, that it almost doesn't matter, that magepets will refuse parts of it.
 
@Myysterio Man your killing me. I still have mererging in the changes to the pettoy's routine, but there is a whole list of other things I need to finish first.
 
To return to the mages running to their doom after equipping their pets:
I've tracked down the issue to this line at the bottom of the Sub Pettoys section which is causing the issue:
INI:
/call DoWeMove ${ReturnToCamp} PetToys
This line will 100% of the time force the mage to return to their camp spot after summoning pet toys as far as I can tell. The problem arises where the ReturnToCamp coordinates are set in the variables when you start the macro, even if the ReturnToCamp variable is disabled. So what happens is that this sub completes, and the macro instantly calls a return to camp call, making the mage navigate back to those camp coordinates, wherever they my be. I resolved the issue simply by controlling it with an if check:
INI:
    /if (${ReturnToCamp}) /call DoWeMove 1 PetToys
Which will only call the move command IF you have ReturnToCamp enabled in your ini. I do realize the purpose of the call to return your toon to your camp location after they moved off to hand over the toys, however; that's only pertinent if you actually have "set" a camp first.

A more robust fix would be to store your camp coordinates in a string, call CampHere on at the beginning of the pet sub to set a new camp location temporarily, summon the toys and hand them out, then call the return to camp and redefine your camp coordinates back to the original. I find this excessively complicated, and would rather just not call ReturnToCamp if it's not turned on. If I'm chasing/following/sticking, then the mage will stay with the MA anyway, if not, then everyone's free form standing around, and there's not really any reason to call a ReturnToCamp. Otherwise the wait subs would be checking location and returning you to your camp coordinates regardless if you are utilizing the ReturnToCamp functionality, so no need to reinvent the wheel, but that's my viewpoint.

So far this has completely resolved my mage suicide squad in the past month of testing, so I wanted to put it out there for others that might still be suffering from this issue.
 
Snippet - Enhanced Sub PetToys for KA12

Users who are viewing this thread

Back
Top
Cart