Jump to content

Detecting invisible creature at range


Salk

Recommended Posts

Hi again!

 

I wanted my guard to become hostile if any GOODCUTOFF creature would get too close but I seem I cannot find a way to do it right because from what I understand, NEAREST only works with visible creature and the StateCheck is never returning true.

IF
    Range(NearestMyGroupOfType([GOODCUTOFF]),5)
    StateCheck(NearestMyGroupOfType([GOODCUTOFF]),STATE_INVISIBLE)
    Global("Hostile","LOCALS",0)
THEN
      RESPONSE #100
        FaceObject(NearestMyGroupOfType([GOODCUTOFF]))
        SetGlobal("AlarmShout","GLOBAL",99)
        SetGlobal("Hostile","LOCALS",1)
END

 

Any ideas (that does not require the active creature to see through invisibility, that is...)?

 

Thanks!

Link to comment

If ANY goodcutoff could make it hostile, then change it to Range([GOODCUTOFF],5)

Also, you don't need to check invis, because range would not 'see' invis creatures anyway (iirc).

Even if it would, you need NotStateCheck, because the above check would be 'true' when the creature is invis. Again, since range would never pass for an invis creature, except if your creature has the detect invis by script stat, obviously, the statecheck would never return true.

Link to comment

IF

Range([GOODCUTOFF],5)

StateCheck([GOODCUTOFF],STATE_INVISIBLE)

Global("hostile","locals",0)

THEN

...

END

 

Range() should definitely recognize invisible objects (unless I confuse with being checked by area triggers instead of actors?..). Even if it doesn't, you can still adjust it to Detect() instead:

 

IF

Detect([GOODCUTOFF])

Range(LastSeenBy(Myself),5)

StateCheck(LastSeenBy(Myself),STATE_INVISIBLE)

Global("hostile","locals",0)

THEN

...

END

Link to comment

Ardanis,

 

the first does not work. But even if it worked, I have a technical question: would it trigger also in case one other GOODCUTOFF creature (not that in the right range) would be invisible?

 

The second does. I did not think of it myself because I did not think that an invisible creature could become object using LastSeenBy + Detect (IESDP is ambiguous because it says "Neither Move Silently and Hide in Shadows prevent creatures being detected via Detect()" - it would have been better to change to "Invisibility does not prevent creatures being detected via Detect()".

 

Good solution though, thanks!

Link to comment
the first does not work. But even if it worked, I have a technical question: would it trigger also in case one other GOODCUTOFF creature (not that in the right range) would be invisible?

 

No, the one in range would be [GOODCUTOFF], while the other would need to be matched by SecondNearest([GOODCUTOFF]) to return true.

Link to comment

Thanks a lot for sharing your knowledge.

 

I truly appreciate it.

 

I have been trying to work more on my scripts and perhaps you can give me some advice again.

 

First, I wanted my guard ("thiefg") to become hostile if one party member (Player1 in the code below) becomes invisible before him or if the party member becomes visible without having been seen before (the local variable "InSight[1-6]" keeps track of visibility/invisibility).

 

In order to do that, I created these two blocks:

IF
    Global("Hostile","LOCALS",0)
    Global("InSight1","LOCALS",0) // I am visible and in visual range
    !See(Player1)
    TriggerOverride(Player1,See("thiefg"))
THEN
       RESPONSE #100
        SetGlobal("Hostile","LOCALS",1)
        SetGlobal("AlarmShout","GLOBAL",99)
END

and

IF
    Global("Hostile","LOCALS",0)
    Global("InSight1","LOCALS",3) // I am invisible but in visual range
    See(Player1)
THEN
       RESPONSE #100
        SetGlobal("Hostile","LOCALS",1)
        SetGlobal("AlarmShout","GLOBAL",99)
END

The problem is that the first block triggers even if Player1 enters the area already invisible.

 

Is there a way to prevent this from happening?

 

Thanks again for your help.

Link to comment
The problem is that the first block triggers even if Player1 enters the area already invisible.

 

Without having to re-analyze the already existing script, the simplest solution is probably to use the value 0 of InSight1 as "not initialized" rather than "visible and in range". Would likely need to just increase the value set and checked by 1 in non-initial blocks.

Link to comment

Well, the way I solved this was surely sub-par and introduces a bunch of global variables as well (6, one for each party member).

In my revision, the Thieves Guild HQ won't be accessible unless the password is provided or an alarm is raised so the only exit until then is back to AR7800.

I extended AR7800 (Baldur's Gate East) with this:

IF
    Global("PL1INV","GLOBAL",0)
    AreaCheckObject("AR7800",Player1)
    StateCheck(Player1,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL1INV","GLOBAL",1) // Player1 is invisible
END

IF
    Global("PL2INV","GLOBAL",0)
    AreaCheckObject("AR7800",Player2)
    StateCheck(Player2,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL2INV","GLOBAL",1) // Player2 is invisible
END

IF
    Global("PL3INV","GLOBAL",0)
    AreaCheckObject("AR7800",Player3)
    StateCheck(Player3,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL3INV","GLOBAL",1) // ...and so on
END

IF
    Global("PL4INV","GLOBAL",0)
    AreaCheckObject("AR7800",Player4)
    StateCheck(Player4,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL4INV","GLOBAL",1)
END

IF
    Global("PL5INV","GLOBAL",0)
    AreaCheckObject("AR7800",Player5)
    StateCheck(Player5,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL5INV","GLOBAL",1)
END

IF
    Global("PL6INV","GLOBAL",0)
    AreaCheckObject("AR7800",Player6)
    StateCheck(Player6,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL6INV","GLOBAL",1)
END

IF
    Global("PL1INV","GLOBAL",1)
    AreaCheckObject("AR7800",Player1)
    NotStateCheck(Player1,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL1INV","GLOBAL",0) // Player 1 is not invisible
END

IF
    Global("PL2INV","GLOBAL",1)
    AreaCheckObject("AR7800",Player2)
    NotStateCheck(Player2,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL2INV","GLOBAL",0) // Player2 is not invisible
END

IF
    Global("PL3INV","GLOBAL",1)
    AreaCheckObject("AR7800",Player3)
    NotStateCheck(Player3,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL3INV","GLOBAL",0) // and so on...
END

IF
    Global("PL4INV","GLOBAL",1)
    AreaCheckObject("AR7800",Player4)
    NotStateCheck(Player4,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL4INV","GLOBAL",0)
END

IF
    Global("PL5INV","GLOBAL",1)
    AreaCheckObject("AR7800",Player5)
    NotStateCheck(Player5,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL5INV","GLOBAL",0)
END

IF
    Global("PL6INV","GLOBAL",1)
    AreaCheckObject("AR7800",Player6)
    NotStateCheck(Player6,STATE_INVISIBLE)
THEN
    RESPONSE #100
        SetGlobal("PL6INV","GLOBAL",0)
END


Then I added this to the script of the Guard:

IF
    Global("PL1INV","GLOBAL",1)
    See(Player1)
THEN
       RESPONSE #100
        SetGlobal("PL1INV","GLOBAL",2) // This raises the alarm - Player1 entered the area invisible and became visible before the guard
END

IF
    Global("PL2INV","GLOBAL",1)
    See(Player2)
THEN
       RESPONSE #100
        SetGlobal("PL2INV","GLOBAL",2) // This raises the alarm - Player2 entered the area invisible and became visible before the guard
END

IF
    Global("PL3INV","GLOBAL",1)
    See(Player3)
THEN
       RESPONSE #100
        SetGlobal("PL3INV","GLOBAL",2) // ...and so on
END

IF
    Global("PL4INV","GLOBAL",1)
    See(Player4)
THEN
       RESPONSE #100
        SetGlobal("PL4INV","GLOBAL",2)
END

IF
    Global("PL5INV","GLOBAL",1)
    See(Player5)
THEN
       RESPONSE #100
        SetGlobal("PL5INV","GLOBAL",2)
END

IF
    Global("PL6INV","GLOBAL",1)
    See(Player6)
THEN
       RESPONSE #100
        SetGlobal("PL6INV","GLOBAL",2)
END



I am not sure I understood the method you were suggesting, Ardanis. The problem for me is that I cannot find a way other than this to make the guard behave differently depending on whether or not the invisibility is from transitioning to his area or not. I was hoping OnCreation() might help me but I failed with that too.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...