Jump to content


Photo

Detecting invisible creature at range


8 replies to this topic

#1 Salk

Salk
  • Modders
  • 2854 posts
  • Gender:Male
  • Location:Sweden

Posted 06 March 2017 - 03:24 AM

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!



#2 Avenger

Avenger
  • Modders
  • 3663 posts
  • Gender:Male
  • Location:Hungary

Posted 06 March 2017 - 08:26 AM

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.



#3 Ardanis

Ardanis

    A very GAR character

  • Modders
  • 2496 posts
  • Gender:Male
  • Location:Saint-Petersburg, Russia

Posted 06 March 2017 - 09:24 AM

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


Edited by Ardanis, 06 March 2017 - 09:25 AM.

"Uguu~ Boku Ayu."

Before you start breaking wall tiles with your bare fists, ask yourself first - do you truly need it?

#4 Salk

Salk
  • Modders
  • 2854 posts
  • Gender:Male
  • Location:Sweden

Posted 06 March 2017 - 07:48 PM

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!


Edited by Salk, 06 March 2017 - 07:59 PM.


#5 Ardanis

Ardanis

    A very GAR character

  • Modders
  • 2496 posts
  • Gender:Male
  • Location:Saint-Petersburg, Russia

Posted 06 March 2017 - 08:37 PM

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.


"Uguu~ Boku Ayu."

Before you start breaking wall tiles with your bare fists, ask yourself first - do you truly need it?

#6 Salk

Salk
  • Modders
  • 2854 posts
  • Gender:Male
  • Location:Sweden

Posted 07 March 2017 - 02:30 AM

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.


Edited by Salk, 07 March 2017 - 03:32 AM.


#7 Avenger

Avenger
  • Modders
  • 3663 posts
  • Gender:Male
  • Location:Hungary

Posted 07 March 2017 - 10:22 AM

Ah, i didn't know you wanted to be hostile if there is an invis person nearby :D 



#8 Ardanis

Ardanis

    A very GAR character

  • Modders
  • 2496 posts
  • Gender:Male
  • Location:Saint-Petersburg, Russia

Posted 07 March 2017 - 01:59 PM

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.


"Uguu~ Boku Ayu."

Before you start breaking wall tiles with your bare fists, ask yourself first - do you truly need it?

#9 Salk

Salk
  • Modders
  • 2854 posts
  • Gender:Male
  • Location:Sweden

Posted 07 March 2017 - 10:33 PM

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.


Edited by Salk, 07 March 2017 - 10:35 PM.




Reply to this topic



  


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users