argent77 Posted April 28, 2021 Share Posted April 28, 2021 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. Quote Link to comment
temnix Posted April 28, 2021 Share Posted April 28, 2021 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. Quote Link to comment
argent77 Posted April 29, 2021 Author Share Posted April 29, 2021 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. Quote Link to comment
Luke Posted April 29, 2021 Share Posted April 29, 2021 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)) Quote Link to comment
argent77 Posted April 29, 2021 Author Share Posted April 29, 2021 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... Quote Link to comment
temnix Posted May 1, 2021 Share Posted May 1, 2021 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. Quote Link to comment
argent77 Posted May 1, 2021 Author Share Posted May 1, 2021 (edited) 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 May 1, 2021 by argent77 Quote Link to comment
Recommended Posts
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.