What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

How to activate a shrine from within a combat routine?

Bantou

Active Member
Joined
Feb 22, 2012
Messages
201
Reaction score
151
My combat routine can make the bot run up to the shrine ok, but starts twerking all around it, and doesn't seem to know how to click it. I'd simply like to know what Demonbuddy code to reference from within the routine to have it activate the shrine and not just run up to it. If any Dev can answer me that would be much appreciated. Here's a link to the combat routine in it's current release state:- https://www.thebuddyforum.com/threads/necromancer-rathma-faceroll-glass-cannon-gr-95.402497/ If any Dev would like to review the change I'm trying to make, and how I've coded it so far, I'll be more than happy to shoot them a copy.

Thanks in advance, Bantou :D
 
I was under the impression that all you had to do was declare a ShrineRange and the rest was automatic - the base default routines don't have any shrine code in them other than this:

Code:
public virtual float ShrineRange => 80f;

Some of the wizard routines have a teleport to shrine section of code that is separate, like this:

Code:
            if (CurrentTarget.Distance < 50 && isShrine || isProgressionGlobe || (isHealthGlobe && archonHealthIsLow))
            {
                //Core.Logger.Log($"Teleporting to Priority Target");
                position = CurrentTarget.Position;
                return true;
            }

If all you want is to trigger them, it should just be a matter of setting ShrineRange and appropriate settings in DB. If you're trying for something more complex, that should work too. I took a quick look at your code and you have some more complex shrine-related stuff in there, it's possible that is messing with the default shrine activation. As a test, you could strip that out, just add the ShrineRange, and if that works add on top and test again. Makes it easy to find what's breaking the normal behavior.
 
I was under the impression that all you had to do was declare a ShrineRange and the rest was automatic - the base default routines don't have any shrine code in them other than this:

Code:
public virtual float ShrineRange => 80f;

Some of the wizard routines have a teleport to shrine section of code that is separate, like this:

Code:
            if (CurrentTarget.Distance < 50 && isShrine || isProgressionGlobe || (isHealthGlobe && archonHealthIsLow))
            {
                //Core.Logger.Log($"Teleporting to Priority Target");
                position = CurrentTarget.Position;
                return true;
            }

If all you want is to trigger them, it should just be a matter of setting ShrineRange and appropriate settings in DB. If you're trying for something more complex, that should work too. I took a quick look at your code and you have some more complex shrine-related stuff in there, it's possible that is messing with the default shrine activation. As a test, you could strip that out, just add the ShrineRange, and if that works add on top and test again. Makes it easy to find what's breaking the normal behavior.

I've disabled all Trinity globe collection and shrine activation while in combat. I was told I could just shrineTarget.Interact(), but thus far haven't had much success. I'm trying to take charge of when globes are collected and shrines are activated while in combat, and all is working well but the shrine activation. I suppose there must be something that I'm missing, and perhaps there is a better way, but at this stage I don't know. While I may be able to make some use of your suggestion (thank you), it doesn't solve my present dilemma :(

Thanks again :)
 
I've disabled all Trinity globe collection and shrine activation while in combat. I was told I could just shrineTarget.Interact(), but thus far haven't had much success. I'm trying to take charge of when globes are collected and shrines are activated while in combat, and all is working well but the shrine activation. I suppose there must be something that I'm missing, and perhaps there is a better way, but at this stage I don't know. While I may be able to make some use of your suggestion (thank you), it doesn't solve my present dilemma :(

Thanks again :)
Ah, I didn't realize you were disabling the built-in. I'll dive into the Trinity source in a bit and see if I can find what you're looking for.
 
Ah, I didn't realize you were disabling the built-in. I'll dive into the Trinity source in a bit and see if I can find what you're looking for.

Thanks heaps, it's starting to look like that might be the last missing piece of the puzzle, then I can move on to something else ;)
 
Ok, I've looked through all your logic and the Interact() logic in Trinity... but it's a little hard to figure out since I don't have a necro to test.

Interact() itself has two different routines, one in TrinityActor that stops the player, does a case switch on Gizmo (which a Shrine should be), then uses a power to activate:

Code:
        public bool Interact()
        {
            Navigator.PlayerMover.MoveStop();

            switch (ActorType)
            {
                case ActorType.Monster:
                    return ZetaDia.Me.UsePower(SNOPower.Axe_Operate_NPC, Vector3.Zero, 0, AcdId);
                case ActorType.Gizmo:
                case ActorType.Item:
                    return ZetaDia.Me.UsePower(SNOPower.Axe_Operate_Gizmo, Vector3.Zero, 0, AcdId);
                default:
                    return false;
            }
        }

For all intents and purposes, that part looks good.

There's a private method in MoveToAndInteract which is slightly different, but I don't think we need to worry about that.

If I look for an example of Interact() elsewhere, you can find this:

Code:
            if (ZetaDia.IsInTown && !ZetaDia.Globals.IsLoadingWorld)
            {
                Core.Logger.Log("Trying again to use return portal.");
                var gizmo = ZetaDia.Actors.GetActorsOfType<DiaGizmo>().FirstOrDefault(g => g.ActorInfo.GizmoType == GizmoType.HearthPortal);
                if (gizmo != null)
                {
                    await CommonCoroutines.MoveAndStop(gizmo.Position, 2f, "Portal Position");
                    await Coroutine.Sleep(1000);
                    gizmo.Interact();
                    gizmo.Interact();
                }
            }

Pretty straightforward, searches for HearthPortals in all DiaGizmo actors, picks the first, null tests it, moves and stops, then interacts twice. I'm guessing that's to make sure it actually interacts.

Here's a dump of a shrine I just found in game:

Code:
ActorId: 176074, Type: Gizmo, Name: Shrine_Global_Blessed-5166, Distance2d: 3087.256, CollisionRadius: 10.04086, MinimapActive: 1, MinimapIconOverride: -1, MinimapDisableArrow: 0

And finally, the experimental code you have:

Code:
        private TrinityActor FindShrine(float range = 60f)
        {
            TrinityActor target = null;

            target = TargetUtil.SafeList().Where(a => a?.Type == TrinityObjectType.Shrine && a.Distance < range).OrderBy(a => a.Distance).FirstOrDefault();
            return target;
        }

            /*
            shrineTarget = FindShrine();
            if (shrineTarget != null)
            {
                if (shrineTarget.Position.Distance(closestTarget.Position) >= shrineTarget.Position.Distance(Player.Position) && !shrineTarget.IsAvoidanceOnPath)
                {
                    if (shrineTarget.Position.Distance(Player.Position) <= 7f)
                    {
                        target.Interact();
                        return false;
                    }
                    else
                    {
                        destination = shrineTarget.Position;
                        return true;
                    }
                }
            }
            */

Based on that, I have a few suggestions to try. I would have tested them, but again I don't have a necro leveled up enough.

1. Add a bunch of logging statements throughout your logic to make sure it's working where it should and that something else isn't hanging up.
2. Try changing your FindShrine to something like the other interact code above if the logging statements show an issue with the logic itself.
3. Instead of interact, you can try clicking it directly:

Code:
ZetaDia.Me.UsePower(SNOPower.Axe_Operate_Gizmo, target.Position);
 
Ok, I've looked through all your logic and the Interact() logic in Trinity... but it's a little hard to figure out since I don't have a necro to test.

Interact() itself has two different routines, one in TrinityActor that stops the player, does a case switch on Gizmo (which a Shrine should be), then uses a power to activate:

Code:
        public bool Interact()
        {
            Navigator.PlayerMover.MoveStop();

            switch (ActorType)
            {
                case ActorType.Monster:
                    return ZetaDia.Me.UsePower(SNOPower.Axe_Operate_NPC, Vector3.Zero, 0, AcdId);
                case ActorType.Gizmo:
                case ActorType.Item:
                    return ZetaDia.Me.UsePower(SNOPower.Axe_Operate_Gizmo, Vector3.Zero, 0, AcdId);
                default:
                    return false;
            }
        }

For all intents and purposes, that part looks good.

There's a private method in MoveToAndInteract which is slightly different, but I don't think we need to worry about that.

If I look for an example of Interact() elsewhere, you can find this:

Code:
            if (ZetaDia.IsInTown && !ZetaDia.Globals.IsLoadingWorld)
            {
                Core.Logger.Log("Trying again to use return portal.");
                var gizmo = ZetaDia.Actors.GetActorsOfType<DiaGizmo>().FirstOrDefault(g => g.ActorInfo.GizmoType == GizmoType.HearthPortal);
                if (gizmo != null)
                {
                    await CommonCoroutines.MoveAndStop(gizmo.Position, 2f, "Portal Position");
                    await Coroutine.Sleep(1000);
                    gizmo.Interact();
                    gizmo.Interact();
                }
            }

Pretty straightforward, searches for HearthPortals in all DiaGizmo actors, picks the first, null tests it, moves and stops, then interacts twice. I'm guessing that's to make sure it actually interacts.

Here's a dump of a shrine I just found in game:

Code:
ActorId: 176074, Type: Gizmo, Name: Shrine_Global_Blessed-5166, Distance2d: 3087.256, CollisionRadius: 10.04086, MinimapActive: 1, MinimapIconOverride: -1, MinimapDisableArrow: 0

And finally, the experimental code you have:

Code:
        private TrinityActor FindShrine(float range = 60f)
        {
            TrinityActor target = null;

            target = TargetUtil.SafeList().Where(a => a?.Type == TrinityObjectType.Shrine && a.Distance < range).OrderBy(a => a.Distance).FirstOrDefault();
            return target;
        }

            /*
            shrineTarget = FindShrine();
            if (shrineTarget != null)
            {
                if (shrineTarget.Position.Distance(closestTarget.Position) >= shrineTarget.Position.Distance(Player.Position) && !shrineTarget.IsAvoidanceOnPath)
                {
                    if (shrineTarget.Position.Distance(Player.Position) <= 7f)
                    {
                        target.Interact();
                        return false;
                    }
                    else
                    {
                        destination = shrineTarget.Position;
                        return true;
                    }
                }
            }
            */

Based on that, I have a few suggestions to try. I would have tested them, but again I don't have a necro leveled up enough.

1. Add a bunch of logging statements throughout your logic to make sure it's working where it should and that something else isn't hanging up.
2. Try changing your FindShrine to something like the other interact code above if the logging statements show an issue with the logic itself.
3. Instead of interact, you can try clicking it directly:

Code:
ZetaDia.Me.UsePower(SNOPower.Axe_Operate_Gizmo, target.Position);

Haha thanks so much, this gives me a lot to play with, I think I have some fun hours ahead :P

I really appreciate the time you've taken :D
 
Let me know if you figure it out, because now I'm curious. I'm leveling a necro right now to try it :P
 
Let me know if you figure it out, because now I'm curious. I'm leveling a necro right now to try it :p

I got sidetracked fixing other things yesterday, and today I think I'll be out most of the day, but tomorrow I should definitely be able to get stuck into it ;) You also gave me an idea for significant improvements to the way I handle movement too so ... :P

I hope you like the Necro :D
 
Back
Top