• 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

Idea - "Should we streamline movement behavior in KA? Why? How would it look?"

Redbot

💻❤️
Moderator
Joined
Oct 15, 2004
RedCents
104,058¢
Pronouns
He/Him
If you were to redo KissAssist's movement, what would it look like? Why would you change it?

Here's one idea to start things off,

There's an absolutely insane amount of calls to /moveto and /stick in the macro. I've found that KA doesn't much care for StickHow and a large portion of the sticks don't use it. I would like to see (when loaded) KA use Nav for moving to a destination, or to a target because sometimes group placement doesn't allow for stick to handle getting to a target and I end up running into a wall trying to get to a mob in tight corners. I've used a pair of function, one of which checks for nav, and one which checks for stick during combat where if there is no line of sight and a path is available it will use nav, and otherwise if it has line of sight or nav doesn't have a valid nav location to use stick. I've had good luck with this experience and feed back from users suggests this works better overall. MQ2Nav is getting put in the spotlight a lot with the mesh library and updater and it's very common these days for a player to have a mesh available for navigating in pretty much any zone they are in. The movement issues are probably best displayed on the bard, but I've experienced a lot of weird behavior overall as far as movement goes and I feel that's a major part of my issue with the macro at this time.
 
Last edited:
Well writing a plugin and writing a macro are of course two different animals. I've debated on the details of how I might approach it, and honestly without more understanding of the macro as a whole it's really hard to say. But I believe any movement involving engaging a target should be handled with a function and not a /moveto and not a /stick and not a /nav. It should be determined within the function the best approach to use.

Let us say that we have determined that it's time to engage the target, and we need to know the best way to do so. I'd need to decide how to approach that movement by first ensuring that I wasn't using any other method of movement. Since KA uses /moveto, /stick, and /nav I would start by ensuring that none of those are currently active, and if they are then I'd need to switch them off so that I could issue my new command.

C++:
void ShouldIStick() {
    if (!bUseStick) return;
    if (Casting()) return;
    if (iPluginMode != MODE_MANUAL) {
        if (HandleMoveUtils() && (*pbStickOn == false || (TargetOfTarget() && Me() && TargetOfTarget()->SpawnID == Me()->SpawnID && StickMode != Have_Aggro) || (TargetOfTarget() && Me() && TargetOfTarget()->SpawnID != Me()->SpawnID && StickMode != No_Aggro && iPluginMode != MODE_PULLERTANK && iPluginMode != MODE_TANK)) && (!NavActive() || LineOfSight(Me(), MyTarget()))) {
            if (NavActive())
                NavEnd();

            if (TargetOfTarget() && Me() && TargetOfTarget()->SpawnID == Me()->SpawnID || (iPluginMode == MODE_TANK || iPluginMode == MODE_PULLERTANK)) {
                if (StickMode != Have_Aggro) {
                    Stick(StickHaveAggro);
                    StickMode = Have_Aggro;
                }
            }
            else if (TargetOfTarget() && Me() && TargetOfTarget()->SpawnID != Me()->SpawnID && StickMode != No_Aggro || *pbStickOn == false) {
                Stick(StickHow);
                StickMode = No_Aggro;
            }

        }
    }
}

C++:
void ShouldINav() {
    if (iPluginMode != MODE_MANUAL) {
        if (!ValidTarget(MyTargetID())) {
            if (IsAttackOn()) {
                AttackOff();
            }
            ClearTarget();
            return;
        }
        if (PSPAWNINFO pSpawn = (PSPAWNINFO)GetSpawnByID(MyTargetID())) {
            if ((!bUseStick || !LineOfSight(Me(), pSpawn)) && Get3DDistance(pSpawn->X, pSpawn->Y, pSpawn->Z, Me()->X, Me()->Y, Me()->Z) > 15) {
                if (!NavActive()) {

                    NavigateToID(pSpawn->SpawnID);
                }
            }
            if (AmFacing(pSpawn->SpawnID) > 10) Face(GetCharInfo()->pSpawn, "fast");
        }
    }
}

Those are my two movement commands that are done for the combat routine for all classes currently. Being mindful that the plugin loops repeatedly approximately every 0.4 to 0.6 seconds though all the logic. But, if attack is on the following is done by all classes (Though this is subject to change as I'm currently in the process of adding casters)

C++:
bool CommonCombatDPS() {
    PSPAWNINFO me = (PSPAWNINFO)GetCharInfo()->pSpawn;
    if (!me || !MyTarget() || !MyTargetID() || MyTargetID() == me->SpawnID) {
        if (IsAttackOn())
            AttackOff();
        return false;
    }
    SwitchWithMACheck();
    if (!Casting()) {
        ShouldINav();
        ShouldIStick();
    }
    if (PullTarget) PullTarget = 0;
    return true;
}

So I'm saying in this CommonCombatDPS() function that if I exist in game, lets look at some reasons to stop attacking, or not do any movement.

If I don't have a target, or I'm targeting myself, I want to turn off attack and leave the Common DPS checks. (Targeting yourself may be valid during combat for non-melee classes who do actually cast buffs, and this situation will be revisited for my plugins soon as I make the cleric)

Then I do a check for the function that auto switches with the MA, which just say if the MA's target is different than my target to switch to their current target, but only if SwitchWithMA is true.

Then, if I'm not currently casting anything, check those two functions. ShouldINav and ShouldIStick.

If I'm in combat, and I had a designated pull target, I want to clear it, because I'll need to re-evaluate my pull target after combat because it's possible something else has spawned, or the spawn I had wanted to pull has now moved.

then I return. The return being true or false is an indication on if I should continue to process the rest of the normal combat routine. So if I didn't have a target, or the target was myself in this case I would return false, and I wouldn't finish the rest of the combat routine.

Note that nothing in this routine has me locked to a specific target with the exception of SwitchWithMA() check which is designed to make me target anything the MA targets. (WIP)

For the movement stuff ShouldINav and ShouldIStick, in both cases we check for a valid target. KA does this in their code, so I shouldn't have to explain this part. This just ensures that the target I have right now is a valid combat target, and if it isn't it will turn off attack and clear my target.

For the actual part where navigation/movement happens I honestly only need to check a few things.

bUseStick is a bool value that stores if the user wants to use MQ2MoveUtils to stick to their target, which allows them to use the StickHow method to stick behind a target, or to the left and right sides. If that's not on, then we're going to always use nav.
!LineOfSight is making saying if I don't have line of sight, then I want to use nav, because I can't see my target to hit them. I do NOT want to pass this function and use stick in that case because if I can't see my target then sticks straight line distance engage isn't going to work, and finally If the distance from me to the mob is greater than 15 (exceeds melee distance in most cases at about 18 distance). With that said, this of course assumes some things and would need to be modified for caster classes to allow the casters to not stand right on top of the mobs they are engaging.

So if I pass that and nav is not currently active. I need to navigate to the target. then, because in some cases nav doesn't actually move, I may need to make the user face their target, I issue a face command so they face the enemy.

For ShouldIStick
I again check for bUseStick, and if it's false we just leave the function because we don't want to use stick to get to the target.
HandleMoveUtils just validates I have access to the pbStickOn pointer, and that the plugin mq2moveutils is loaded.
*pbStickOn is checking is stick is currently active by comparing it to false, there are macro equivilents to this in KA that can be used.

Stick mode includes new information that wasn't located in the ShouldINav function, and it's related to "StickMode" and "StickHow"

StickMode determines what mode of sticking I'm currently using. If I'm "/stick behind 10 uw" then StickMode is No_Aggro which is 2. and StickMode Have_Aggro is 1. This keeps track of how I am sticking using an int as opposed to me asking MQ2MoveUtils to tell me what it's doing.

So which "StickMode" to use in this case is determined based on if I'm the TargetOfTarget of the NPC I'm currently targeting. So if the mob wants to eat me, then I just /stick, if the mob is interested in someone else, I want to /stick behind.

So as long as I don't have aggro I'm using the StickHow. provided by the user. Otherwise it's preset to not spin in circles around the mob trying to stay behind or to the left/right of the mob.


For the movement to camp, from camp, or to chase the MA. I 100% recommend using another function, or duplicating the method you travel in those various places. IE: a function for MoveToLoc, which takes the XYZ destination and determines the best method similar to the approach I've taken for the above combat routine.

In dungeons, you may not have a direct path back to camp, and /moveto will run into walls and all sorts of silly things trying to get back because it has no concept of walls, or other barriers. When a mesh is loaded and a path exists, I would use Nav 100% of the time. If there is no mesh loaded, then I could see just making it work with a /moveto command because you no longer have an option of using recast navigation to travel back to the camp.

The same for following in chase mode. Navigation should be used anytime it's possible to use navigation because it's the most accurate method of getting to a destination.

I realize that traveling using nav was not more widely adopted until more recently so I'm not knocking the methods that were used because they were certainly valid in their time, but with the addition of the mesh updater and repositories, we'd certainly want to use that method of travel where ever and when ever it's possible.

My plugins don't use /moveto or /stick at all, but KA is already setup to use those methods. So adding logic to try to use nav to the top of any existing attempts to /moveto should prove more time consuming than it would be complicated.


100% of my movement issues with KA revolve around the multiple methods of movement, and two of them fighting each other for control of the character. The character tries to return to camp, but something else is trying to get them to engage in combat. So instead of finishing either of them, they are just locked in place where they are standing spinning in circles with neither method of movement winning the battle. This has been most obvious on my bard, where it runs out to engage in combat, finishes a fight, tries to return to camp, but another mob comes in, now mid movement they're told to stick to the mob but a /moveto is still active somewhere.

This is the part where I'm saying we should be checking and ending any other movement. Theres ${MoveTo} and ${Stick} datatypes available that allow you to make sure one or the other isn't running when you attempt to use the command. For the case of kissassist stick is trying to attach to something specific. Like a player or a mob. I believe the priority should be given to Stick over MoveTo as moveto is trying to arrive at a destination, but if we need to follow a mob or player then we should end any /moveto commands then process with issuing a stick command. The wiki for MQ2MoveUtils was greatly expanded a while back to include all the details of these TLO's so that we can approach them with as much information possible available to us.

Keep in mind that this all sounds good in practice, implementation might not be as straight forward as it sounds in this writeup.

There's over 70 /stick commands issues through-out KissAssist.mac, about half that many /moveto commands issued, and a fair amount of nav commands issued. Going through and find each one of these and recoding it to use some predefined method such as the one documented here is surely going to be a monster of a task. I had the luxury of writing all of my movement while I was writing all the logic with this thought process in mind. Recoding it to do things differently, especially not being the original author of any of the logic will surely be mind numbing, and a process that should be expected to take a while.

1577022377984.png
1577022490368.png
The above screenshots are a result of "Find all in document" for both /stick and /moveto to show the various differences from one moveto/stick command use to the next.


However, once complete would allow you to hopefully reduce the over all amount of code that is stored in memory. Allow the sticking to be consistence, and improve the overall functionality of the macro.
 
StickHow in kiss is used for Combat only. The rest of the macro when /sticking does not use StickHow.

The DoWeMove routine Checks if Nav is loaded and tries to use Navigation First, then checks for advpath and then last checks LOS /moveto.

DoWeChase routine Tries to use Navigation first and then LOS /moveto and then if we get close to whom we are chasing, then we try to Stick.

KissAssist is not fighting against your plugin for movement control, you either need to turn off ReturnToCamp in the Macro or control it from the Plugin. Maybe the plugin should be checking for movement and deciding what to do or not to do, why does it have to be the macro? Every macro has it's own way of controlling movement, I don't think you will get everyone to agree on the best way to check if something else is controlling movement and how to handle it.

There are a hundred different points of view, about using /nav .VS. /Moveto when trying to get position on the mob you are fighting. Most of this issue has to do with camp location and the surrounding terrain. Not all camp locations are stationary as well. If you are having problems gaining LOS on mobs that are coming into camp. Then you have a bigger problem than the macro and/or plugin. No matter what you decide, on how you want to tackle this, you will always find situations where it just won't work. That is a can of worms.

I am open to any suggestions and input.
 
to be clear, the movement issues I experience on my bard are not because of a plugin because I do not have a bard plugin.

This is purely Kissassist that I was experiencing the issues with movement where I was randomly getting stuck during movement. Discussion about the plugin was just showing you how I approached it. I didn't mean to imply I was using both KA and the plugin.

It was also not to say that my way is the right way and that your way is the wrong way. It was simply some insight from one class automator to the next.

I don't think blaming the user for line of sight issues with mobs coming into the camp is the correct approach. My problems are not bigger than a macro or plugin, either one could handle the issue. Sure, it would be a can of worms, but KA with 10k+ lines is certainly a can of worms anytime you make a change there is the potential for fixing one issue and creating 3 more.

My point of view can be heard in my original response, aside from clarification I have nothing more to add.
 
The point of this thread is to reimagine movement in KA. CWTN's point here seems valid,
Rich (BB code):
There's over 70 /stick commands issues through-out KissAssist.mac, about half that many /moveto commands issued, and a fair amount of nav commands issued. Going through and find each one of these and recoding it to use some predefined method such as the one documented here is surely going to be a monster of a task. I had the luxury of writing all of my movement while I was writing all the logic with this thought process in mind. Recoding it to do things differently, especially not being the original author of any of the logic will surely be mind numbing, and a process that should be expected to take a while.

The code is pretty /sticky 😝 . When something goes wrong with movement, doesn't this make it hard to debug? Are there any other disadvantages to the current movement system?
 
I don't fully agree with CWTN's point of view. The /stick commands that are used in kiss are not all based on positioning to a mob. There is a lot of duplicate /stick commands to accommodate for being underwater and some of what he said above is proof that he isn't fully aware of what kiss is doing and why.

Anyone is welcome to join into this discussion and make suggestions I welcome any comments/suggestions.
 
So one thing that'd help me provide feedback is understanding the design philosophy or algorithm sketch on what's intended.

For most normal combat things work fine movement wise for me. Is there a part of movement that isn't working (beyond potentially just removing stuff that doesn't use mq2nav and assume folks have meshes)?

The only times I get particularly frustrated is in water combat and the inability for toons to understand their air is getting short so they can go to the surface. This is probably just low level people's problems though.
 
I think perhaps I tried to over explain.

Let's say I want to stick to something, but in order to do so I first need to make sure that I'm not currently navigating, and I'm not currently using the /moveto. What about a function that it gets passed through instead of /stick, you /call stick. then as parameters to that function you pass the arguments for how you would like to stick. That would allow you to quickly create a function just for sticking, then in that function add two statements to handle nav and moveto stopping. Then execute the /stick command knowing for sure that no other movement will conflict with it.

As an added bonus, you could also put a debug statement in there for DEBUGSTICK or DEBUGMOVEMENT so that in the event there are issues with it you could be sure that you would see all instances of movement because all uses of it are passed through the wrapper function which includes the debug statement.

Then of course you would need a similar wrapper for /nav and /moveto that would allow you to repeat the process for those movement types as well.

I think regardless of how simply you decide to handle the movement issues that others are experiencing, that the important take away from this conversation should be that there is an issue with movement. How you proceed with sorting it out is your choice, I only meant to offer suggestions.

Understand that I'm not pointing just at the stick command because I don't know where the conflict is specifically. I'm only stating that what I experienced on my bard was related to two movement types conflicting with each other and the only thing that was active at the time on the bard was KA and there should have been no external influences that would cause it. So the conflict was internal.

My original response was more pointed at the specific question of how would you approach a redo of the movement, and I put my thoughts out there in regards to that. But in this case I'm thinking if you wanted to keep the current system, it might be intuitive to use the wrapper.
 
Based on some further discussion about movement on Discord. I think I have a few general thoughts on how I would want to see Kiss Movement "look" in the future:
1) Provide an option for mq2melee to handle stick movements -- @kaen01 has outlined where this is currently turned off but we aren't aware of side effects. This also would follow the prior principal of letting some things rely on plugin capabilities.
2) Handle underwater movement better in chase mode and having some means of either alerting the main that folks are running out of air or being able to get breath.
3) Add an option for bow users (or ranged damage folks in general) to find a valid location to /nav to in order to maintain a certain distance range from the mob. In the case of rangers this could include further combat logic that just defaults to melee if a good spot isn't found.

In general, from a behavioral perspective, I haven't seen any fundamental issues with kiss movements as everything seems to use nav by default now that I've experienced.
 
Idea - "Should we streamline movement behavior in KA? Why? How would it look?"

Users who are viewing this thread

Back
Top
Cart