irswat Posted March 11, 2014 Share Posted March 11, 2014 What causes an NPC to return 0 or 1 when using GetDetected? I'm making a sniper mod and I have these custom snipers on sniper towers and I wrote this nifty little script so that the snipers attack from as far away as possible, yet it isnt until I get practically right next to the sniper tower-approx 2000-4000 units away-that the snipers react and start attacking the player.I have some debug code in there using OnDetect and the player will be in range of the sniper, but the sniper is throwing the OnDetect==0 flag, or not detecting the player in other words. I cant help but wonder if this is a line of sight issue as I heard LOS is calculated from the feet! If that is true then that is dumb because feet don't have eyes. How can I overcome this issue? Link to comment Share on other sites More sharing options...
jazzisparis Posted March 11, 2014 Share Posted March 11, 2014 (edited) The detection mechanism in the game and how exactly is detection calculated is not fully-understood and is at least partially hardcoded. You can force an NPC to search for the player (SendAssaultAlarm), but you can't force it to detect the player. At such long ranges you speak of, there is no chance an NPC will detect the player, even in daytime and with a clear LOS. I suggest a "simulated" detection process, and UseWeapon to force attack. Consider the following script: scn SniperModScript ref rSniper short iEvalRange short iRange short bLooking short iEvalDetection short bDetected float fChance begin GameMode if iEvalRange == 0 set iRange to GetDistance player if iRange < 8000 if bLooking == 0 set bLooking to 1 Look player endif if iEvalDetection == 0 set iEvalDetection to 300 if GetLOS player == 0 set bDetected to 0 elseif bDetected == 0 set fChance to 20 + ((8000 - iRange) / 400) if player.IsSneaking set fChance to fChance * (1 - (player.GetAV Sneak / 200)) endif if (GameHour > 19) || (GameHour < 5) set fChance to fChance / 2 endif set bDetected to (fChance > GetRandomPercent) endif if bDetected != (GetCurrentAIPackage == 33) if bDetected if rSniper == 0 set rSniper to GetSelf endif UseWeapon WeapNVGhillieSniperRifle rSniper player -1 0 0 else RemoveScriptPackage EVP endif endif else set iEvalDetection to iEvalDetection - 1 endif else set iEvalRange to 600 set iEvalDetection to 0 if bDetected set bDetected to 0 RemoveScriptPackage EVP endif if bLooking set bLooking to 0 StopLook endif endif else set iEvalRange to iEvalRange - 1 endif end What happens here: Every 10 seconds, the script checks if the player is within 8000 game units. If so, it runs a detection check every five seconds, based on LOS, distance from the player, time of day, whether the player is sneaking, the player's sneak skill, and finally a random percent. The calculated detection chance is from 5 to 40% (this seems realistic and balanced enough to me. You can, of course, tweak it - just remember it is re-evaluated every 5 seconds). If successful, the NPC will start firing at the player, and will not cease until losing LOS - at which point detection checks will resume. Edited March 11, 2014 by jazzisparis Link to comment Share on other sites More sharing options...
irswat Posted March 11, 2014 Author Share Posted March 11, 2014 (edited) thanks a lot JIP. You will be getting huge ups when I release this mod. Will it make a difference if I use this with a guard package attached to reference x marker? I have aggro radius at 20000, combat radius at 20000 with 10x max range multi as we discussed, guard radius at 20000, guard location at 0.After looking at your code I think I was using GetDistance the wrong way, as I was using GetSelf the wrong way! Thanks so much man Edited March 11, 2014 by irswat Link to comment Share on other sites More sharing options...
devinpatterson Posted March 11, 2014 Share Posted March 11, 2014 I suggest a "simulated" detection process, and UseWeapon to force attack. Consider the following script: What happens here: Every 10 seconds, the script checks if the player is within 8000 game units. If so, it runs a detection check every five seconds, based on LOS, distance from the player, time of day, whether the player is sneaking, the player's sneak skill, and finally a random percent. The calculated detection chance is from 5 to 40% (this seems realistic and balanced enough to me. You can, of course, tweak it - just remember it is re-evaluated every 5 seconds). If successful, the NPC will start firing at the player, and will not cease until losing LOS - at which point detection checks will resume. Great script Jazzisparis, it will be awesome to have a mechanic that mimics real sniping. But I was curious, (as a non scripting guy) you mentioned the script checks every 10 seconds if the player is <= 8000 units, and also re-evaluated every 5 seconds. I didn't see a timer in the code, is this a quest script (set at default 5)? And the 5 vs the 10 second just a mistype? Link to comment Share on other sites More sharing options...
irswat Posted March 12, 2014 Author Share Posted March 12, 2014 JIP why do you use -1 with UseWeapon what does that accomplish? What parameters does GetRandomPercent take? (E.G. a low number, high number?) Link to comment Share on other sites More sharing options...
jazzisparis Posted March 12, 2014 Share Posted March 12, 2014 Will it make a difference if I use this with a guard package attached to reference x marker? I have aggro radius at 20000, combat radius at 20000 with 10x max range multi as we discussed, guard radius at 20000, guard location at 0.It won't interfere with the script. You can leave it if you want, but it won't make any difference. Great script Jazzisparis, it will be awesome to have a mechanic that mimics real sniping. But I was curious, (as a non scripting guy) you mentioned the script checks every 10 seconds if the player is <= 8000 units, and also re-evaluated every 5 seconds. I didn't see a timer in the code, is this a quest script (set at default 5)? And the 5 vs the 10 second just a mistype?iEvalRange and iEvalDetection act as timers here. Since object/effect scripts iterate every frame (optimally, 60 times/sec), I prefer counting iterations, instead of measuring actual real-time passage. JIP why do you use -1 with UseWeapon what does that accomplish? What parameters does GetRandomPercent take? (E.G. a low number, high number?)UseWeapon expects a positive integer. Feeding it -1 will make it fire to infinity, until halted by RemoveScriptPackage+EVP.GetRandomPercent takes no parameters and return a random integer in the range of 0-99. Link to comment Share on other sites More sharing options...
irswat Posted March 12, 2014 Author Share Posted March 12, 2014 thank you Link to comment Share on other sites More sharing options...
Recommended Posts