Jump to content

How to check distance between two observed creatures by script?


argent77

Recommended Posts

I'm struggling to find a solution for the following problem:

An observer has to determine the distance between two other creatures within its visual range. Both creatures are already marked as target by the observer.

How can I determine the distance between these two creatures from the observer's point of view? It would suffice to check whether both creatures are within visual range of each other. I've drawn a sketch to visualize the problem.

sketch2.png.ef53a782559b2d4521db4ab9cc3e874e.png

Link to comment

You will need to use TriggerOverride to switch to range measuring from Creature A. But this would make Observer lose track of creature B. Also A needs some definite handle to home in on B, i.e. a script name or a fixed object designation - Player1 etc., if A is not in visual range of B. Even if A sees B, in practice it takes a handle to lock on to someone securely, things like LastSeenBy, SecondNearest or [ ] identifiers are not reliable. Definitely not in a crowd. If this is for some special situation or system, you can try using shouts. If B is a minion scripted to Shout() or GlobalShout(), you can run a check from Observer with TriggerOverride(LastSummonerOf,Range(LastHeardBy)). It takes about 3 ticks for a shout to register. You can also make B shout even without a special script. So in Observer's script it would go like this:

ActionOverride("b",GlobalShout(98834 - or anything else, it doesn't matter))
SmallWait(3)
- Probably set some kind of global here
Then, in the next block:

IF

- The global
TriggerOverride(LastSummonerOf,Range(LastHeardBy,10))

THEN...

I've used this system to get minions to communicate with each other. Shouts are reliable even in a crowd and don't require line of sight (just make sure the parties aren't silenced or deaf). But even this makes Observer lose the grip on his LastSeenBy. While you are busy with A and B, Observer's LastSeenBy will slip away. It may not be the same creature if you go back to that handle. Then again, if Observer isn't deaf himself, he also heard B, so you can use LastHeardBy here also. The clever part is that neither A nor Observer need to start a new block with an IF and Heard([ANYONE],98834). They heard something, and that's enough. In theory, in big complicated crowds there may be other shouting going on, which may misdirect them in that split second, but that's not much of a risk.

 

Link to comment

Using shouts is an interesting idea, I'll have to do some tests to see how effective it is. Since shouts come with a small delay I guess the observers may appear like stuck for a few moments whenever a shout is initiated.

The situation described in my previous post can happen frequently for multiple "observers" at the same time. It's intended as a way to prevent spirits summoned by the shamanic dance from moving out of the shaman's sight. Otherwise it would cause them to be unsummoned since EE patch 2.6.

Link to comment

It does sound similar to the problem of avoiding friendly fire when casting a non party-friendly spell. For instance, for a Fireball-like spell (from "BDDEFAI.BCS"):

!TriggerOverride(SecondNearest([EVILCUTOFF.0.TROLL]),Range(NearestEnemyOf(Myself),20))

 

Link to comment

Yeah, that's basically how I wanted to implement it. However, in my case I need to tell the overridden creature a more specific target to use for distance calculation. Shout seems to be a complicated but achievable way.

But now after I've given it some more thought, I think it's possible to circumvent the whole shout mechanism since Creature A from the sketch can only be one of the Player[1-6] targets. In that case I just need six identical TriggerOverride blocks each focusing on another PlayerX target.

IF
  InPartySlot(LastSummonerOf(Myself),0) // Player1?
  TriggerOverride(LastSeenBy(Myself),Range(Player1,28))
THEN
  RESPONSE #100
    AttackOneRound(LastSeenBy(Myself))
END

IF
  InPartySlot(LastSummonerOf(Myself),1) // Player2?
  TriggerOverride(LastSeenBy(Myself),Range(Player2,28))
THEN
  RESPONSE #100
    AttackOneRound(LastSeenBy(Myself))
END

// and so on...

 

Link to comment

With this condition any creature seen by this one and within 28 points of Player1 is going to be attacked.

Also I doubt that conditions like the one in Luke's script would work well in practice. Even in a small crowd these SecondNearest checks slip away or take too long, and there is a second check in there. I had a situation with the three spectral Harpers at the Harper base. I wanted them to turn hostile unless one of the party characters in sight actually wore the amulet instead of that item's simply being in the party's possession, possibly in the inventory of someone on another floor. And it was slow-going. The timer almost ran out before the spectres examined and spotted the character, even though the check was simply for HasItemEquipedReal for LastSeenBy.

But what was that about changes to the shaman script from 2.6? Now how did I solve this range problem myself in my mod for shamans... No, that one uses a different mechanism. I just scripted the spirits to disappear unless someone somewhere is doing the shamanic dance.

Link to comment

The code above was just a simplified example, but mechanism itself works well enough for me. I need to determine the right PlayerX target in any case to make shamanic dance persistent across save and reload operations, since LastSummonerOf() target is cleared whenever you load a saved game.

I tested the shouting technique as well. With the right implementation the delay is barely noticeable, so it would have been a good fallback option.

Edited by argent77
Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...