• 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

You might find this useful...

AmericanNero

Seasoned veteran member
Joined
Oct 13, 2020
RedCents
4,709¢
You can replace the Main or any Sub within a macro with another version, without deleting the original, by placing it at the bottom or including at the end. There is no need to touch a line of code in the original... the implications...

[CODE lang="ini" title="Replacing a subroutine is easy as pie"]
||| ---------------------------------------------------------------------------
||| How To Non-Destructively Replace MQ2 Main and Subs
||| ---------------------------------------------------------------------------

||| ---------------------------------------------------------------------------
||| Sub:Main
||| ---------------------------------------------------------------------------
Sub Main

/echo Main 1
/call MySub Hi!
/call MySub Hi there!
/call MySub MQ2
/call MySub MQ2 Rules!

/return

Sub MySub(string MyParam)
/echo MySub 1 received ${MyParam}
/return

Sub MySub(string MyParam1, string MyParam2)
/echo MySub 2 received ${MyParam1} ${MyParam2}
/return

Sub MySub(string MyParam)
/echo MySub 3 received ${MyParam}
/return

Sub MySub(string MyParam1, string MyParam2)
/echo MySub 4 received ${MyParam1} ${MyParam2}
/return

Sub MySub(string MyParam)
/echo MySub 5 received ${MyParam}
/return

Sub MySub(string MyParam1, string MyParam2)
/echo MySub 6 received ${MyParam1} ${MyParam2}
/return

||| ---------------------------------------------------------------------------
||| Sub:Main
||| ---------------------------------------------------------------------------
Sub Main

/echo Main 2
/call MySub Hi!
/call MySub Hi there!
/call MySub MQ2
/call MySub MQ2 Rules!

/return
||| ---------------------------------------------------------------------------

Sub MySub(string MyParam)
/echo MySub 7 received ${MyParam}
/return

Sub MySub(string MyParam1, string MyParam2)
/echo MySub 8 received ${MyParam1} ${MyParam2}
/return

Sub MySub(string MyParam)
/echo MySub 9 received ${MyParam}
/return

Sub MySub(string MyParam1, string MyParam2)
/echo MySub 10 received ${MyParam1} ${MyParam2}
/return

Sub MySub(string MyParam)
/echo MySub 11 received ${MyParam}
/return

Sub MySub(string MyParam1, string MyParam2)
/echo MySub 12 received ${MyParam1} ${MyParam2}
/return

||| ---------------------------------------------------------------------------
||| Sub:Main
||| ---------------------------------------------------------------------------
Sub Main

/echo Main 3
/call MySub Hi!
/call MySub Hi there!
/call MySub MQ2
/call MySub MQ2 Rules!

/return

[/CODE]

Produces this output:

[MQ2] Main 3
[MQ2] MySub 12 received Hi!
[MQ2] MySub 12 received Hi there!
[MQ2] MySub 12 received MQ2
[MQ2] MySub 12 received MQ2 Rules!
 
Last edited:
i dont understand
It seems he is indicating that the last version of a subroutine is the one that actually gets used, and that MQ2 doesn't throw an error at the duplicate symbols. It just uses the last one.

I suppose this could be viewed as a 'feature' to allow you to customize macros with your own implementation of some subs, and to more easily re-implement this customization when new versions of the macro are released without going back in to edit the original code. I suppose you could just include your customized subs in an include file and just add the include when a new version is released.
 
Putting it at the end overwrites the sub with the new version, which allows you to override routines. This is neat, but since you have to modify the original file, not necessarily all that impressive. What would be impressive is if you wrote a macro that included another macro, and then you could override the original macro's subroutines as done in typical inheritance/override programming techniques. In this way, you don't have to modify the original - even if it's your local copy, it would be better to not change it.
 
Putting it at the end overwrites the sub with the new version, which allows you to override routines. This is neat, but since you have to modify the original file, not necessarily all that impressive. What would be impressive is if you wrote a macro that included another macro, and then you could override the original macro's subroutines as done in typical inheritance/override programming techniques. In this way, you don't have to modify the original - even if it's your local copy, it would be better to not change it.
It seems you could achieve the same effect without modifying the original. Just make your own macro file (say, mykissassist.mac) and include the original macro file above your custom subs. Then just run your version of the macro.
 
It seems you could achieve the same effect without modifying the original. Just make your own macro file (say, mykissassist.mac) and include the original macro file above your custom subs. Then just run your version of the macro.
I'm thinking more like an "include" statement :D

INI:
/include original.mac

Sub OrignialSub(string SomeParam)
    // My new stuff here
/return
 
AN - here's an example of how I would approach what you're doing.

Create a new macro. In my example below, I called it MyMac.mac
Include the macro you want to "monkey patch". Yes, the entire Macro. I've tested this and it works fine. I know the mq2 wiki says that it's only for "snippets" of code, but it works fine.
Override the Subroutines you want.
In my example, I include the Fishing macro called "Fish.Mac" that comes with VV.
I wanted to spice up the message a bit that tells me I don't have a fishing pole, so I override the "Broken Pole" Sub - that also handles the fetching of a pole when you start.

You run the new Fishing macro with /mac mymac

INI:
#include Fish.mac

| --------------------------------------------------------------------------------------------
| SUB: Event_BrokenPole
| --------------------------------------------------------------------------------------------
    Sub Event_BrokenPole
    /declare PoleName string local
    /if (${FindItem[Fisherman's Companion].ID} && !${FindItem[Brell's Fishin' Pole].Name.NotEqual["NULL"]}) {
        /info You have a Fisherman's Companion but haven't summoned a damn rod yet.
        /info Let's f'n fix that!
         /useitem "Fisherman's Companion"
        /delay 2s
        /delay 11s !${Me.Casting.ID}
        /autoinventory
        /delay 1s
        /delay 10s !${Cursor.ID}
    }
    /if (${FindItem[=Fishing Pole].ID}) /varset PoleName "Fishing Pole"
    /if (${FindItem[=Kerran Fishing Pole].ID}) /varset PoleName "Kerran Fishing Pole"
    /if (${FindItem[=Aglthin's Fishing Pole].ID}) /varset PoleName "Aglthin's Fishing Pole"
    /if (${FindItem[=Grey Wood Fishing Pole].ID}) /varset PoleName "Grey Wood Fishing Pole"
    /if (${FindItem[=Hintol's Fishing Pole].ID}) /varset PoleName "Hintol's Fishing Pole"
    /if (${FindItem[=KT's Magic Fishing Pole].ID}) /varset PoleName "KT's Magic Fishing Pole"
    /if (${FindItem[=Uliorn's Fishing Pole].ID}) /varset PoleName "Uliorn's Fishing Pole"
    /if (${FindItem[=Brell's Fishin' Pole].ID}) /varset PoleName "Brell's Fishin' Pole"
    /if (${FindItem[=Ancient Fishing Pole].ID}) /varset PoleName "Ancient Fishing Pole"
    /if (${FindItem[=Collapsible Fishing Pole].ID}) /varset PoleName "Collapsible Fishing Pole"
    /if (${FindItem[=Blessed Fishing Rod].ID}) /varset PoleName "Blessed Fishing Rod"
    /if (${FindItem[=The Bone Rod].ID}) /varset PoleName "The Bone Rod"
    /if (${Cursor.ID} != 29193) /itemnotify ${FindItem[${PoleName}].InvSlot} leftmouseup
    /delay 10s ${Cursor.ID}
    /if (${Cursor.ID}) {
        /info Equipping \ar[\aw${PoleName}\ar]\ao in \atmainhand\ao.
        /itemnotify mainhand leftmouseup
        /delay 1s
        /autoinventory
        /delay 1s
        /delay 10s !${Cursor.ID}
    } else {
        /if (${CampWhenDone}) {
            /info You broke or lost your last fishing pole and you have requested I camp.
            /camp desktop
            /endmacro
        } else {
            /info You broke or lost your last fishing pole. Ending.
            /endmacro
        }
    }
    /return
 
The implication is you can patch a release. I work on KA and bugs have been reported which I've fixed, but lag behind because to this point only major releases are made and bugs fixes that need to be released now go unpublished because of undertested bigger scope changes that would potentially break KA for users.

Rather than having to touch the internals of the release, one can issue a patch with updated subs. If those cause problems, then we can revert with simply removing the include at the bottom.

It's actually quite a useful stroke of design oversight (or was it an oversight?) for this type of user environment. We can have two files, one which is the formal release, and then have an incremental patch file as issues are discovered.
 
Last edited:
why dont you just make your own version and be done with it.

Wouldn't it benefit the community to share the include that fixes bugs so that we can enjoy those fixes before they make it into the final distribution?
 
why dont you just make your own version and be done with it.
Well, when you monkey patch something, that's kind of what you're doing - but with the knowledge that other bug fixes will make it into your 'version' without having to lift a finger (unless they're in the Subroutines you're patching...)
 
My preferred way to maintain a copy of kiss -

1) Setup the folder structure -

Code:
Macros/
  - MyBestKiss.mac <- this just includes MyBestKiss/kissassist.mac
  - MyBestKiss/
    - kissassist.mac
    - other required .inc files
    - custom/
      - meaningfulname.inc <- (combat.inc, casting.inc, whatever makes sense)

2) Put it all in git before you start hacking away.

3) In the primary macro, #include your custom stuff up top and then use a standard comment for the required changes -


Code:
| K## Start Custom Additions (Sub Name)
<some macro code>
| K## End Custom Additions (Sub Name)

This makes it easy to locate any changes when you want to port stuff to newer (or very different) versions and keep all your nifty additions.

4) Once everything is tested, delete all the old crappy subs and commit the changes. Now when I go searching through the macro, I don't have all of the kiss baggage, just any headaches I created. If I want the kiss baggage (or fuckled something real good), I can pull the base from git and continue tinker as needed.
 
CT and I had a discussion with Red yesterday. Good things are afoot to help the release and maintenance process.
 
You might find this useful...

Users who are viewing this thread

Back
Top
Cart