irswat Posted March 10, 2014 Share Posted March 10, 2014 (edited) I have this NPC I created called SMSniper01. I created a script. This script called SniperModScript is attached to the NPC as you can see below. The script basically checks how far the player is from the sniper and if less than 30,000 units away will fire at the player until he is dead. I placed this in the GameMode block. http://i57.tinypic.com/xbes8n.png There are three other parts to this script that either add or remove the Snipers' refid to a form list upon loading, upon death, or when the cell resets.I wasn't really seeing the results I expected from the script so I threw some debugging code in there which you can see below. It prints to the screen using MessageEX how far away the sniper is, and what variables are being stored into memory and whether the sniper refid is added or removed from the formlist.When I run the game I see the "Sniper Mod Debug Game Mode" message but none of the other debug messages. It was my understanding that anything in the GameMode block would run every frame so I was expecting to see "Sniper Mod Debug Game Mode" over and over again. Further more the script never prints the other debugging messages and I don't understand why. Lastly the message that the snipers are added to the formlist never appears so I can assume the snipers are not being added to the formlist.If you can help thanks. Ill give you credit when this mod is finished.Here is the script: scn SniperModScript ;How far away is the player float hfPlayer ;1==player is within snipers range int AlertFlag=0 ;refID of sniper ref rSniper ;max range of sniper weapon float WeapMaxRange ;script to check if player is within maxrange of sniper and issue attack command begin GameMode ;debugging message MessageEx "Sniper Mod Debug Game Mode" ;sets sniper refID set rSniper to SMSniper01.GetSelf MessageEx "Sniper refID " rSniper ;sets max range of sniper rifle set WeapMaxRange to GetMaxRange WeapNVGhillieSniperRifle MessageEx "Weapon Max Range " WeapMaxRange label 1 ;gets how far away player is set hfPlayer to player.GetDistance rSniper MessageEx "Player distance from Sniper" hfPlayer ;is player within range of sniper? if hfPlayer <= WeapMaxRange set AlertFlag to 1 ;debug message MessageEx "Distance<= " WeapMaxRange hfPlayer endif ;if player is within range of sniper and player is not dead, look, and then fire weapon if AlertFlag if (player.GetDead == 0) Look rSniper rSniper.Look player ;debug message MessageEx "Distance <=" WeapMaxRange hfPlayer rSniper.UseWeapon WeapNVGhillieSniperRifle rSniper player 6 0 0 0 0 endif endif ;if player is within range of sniper and player is dead, dont fire weapon elseif AlertFlag if player.GetDead set AlertFlag to 0 endif ;if player is within range of sniper and player is still alive after the first volley then repeat elseif (player.GetDead == 0) set hfPlayer to player.GetDistance rSniper if hfPlayer<=WeapMaxRange ;debug message MessageEx "Distance <= " WeapMaxRange hfPlayer goto 1 endif endif ;if player is still alive but is no longer within range, turn off sniper alert elseif (player.GetDead == 0) set hfPlayer to player.GetDistance rSniper if hfPlayer>=WeapMaxRange ;debug message MessageEx "Distance >= " WeapMaxRange hfPlayer set AlertFlag to 0 endif endif endif end begin OnLoad MessageBoxEx "Sniper Mod Debug OnLoad" set rSniper to SMSniper01.GetSelf if (rSniper.IsInList SMSnipers == 0) AddFormToFormList SMSnipers rSniper MessageEx "Sniper Mod removed from form list! " rSniper endif if IsPlayerMovingIntoNewSpace if (rSniper.IsInList SMSnipers) ListRemoveForm rSniper SMSnipers MessageEx "Sniper Mod removed from form list! " rSniper endif endif end Begin OnReset MessageBoxEx "Sniper Mod Debug OnReset" set rSniper to SMSniper01.GetSelf if (rSniper.IsInList SMSnipers) ListRemoveForm rSniper SMSnipers MessageEx "Sniper Mod removed from form list! " rSniper endif end Begin OnDeath MessageBoxEx "Sniper Mod Debug OnDeath" set rSniper to SMSniper01.GetSelf if (rSniper.GetDead) if (rSniper.IsInList SMSnipers) ListRemoveForm rSniper SMSnipers MessageEx "Sniper Mod removed from form list! " rSniper endif endif end Edited March 10, 2014 by irswat Link to comment Share on other sites More sharing options...
irswat Posted March 10, 2014 Author Share Posted March 10, 2014 also this script is attached to the base NPC. If I have 5 snipers in the loaded area this should print out this information from each sniper one at a time right? Link to comment Share on other sites More sharing options...
jazzisparis Posted March 10, 2014 Share Posted March 10, 2014 30k game units away is not practical, considering:A. The maximum range of projectiles is 10k units.B. Most objects are not even loaded in memory when farther than ~12k units from the player. There are several problems in your script. I will point out only some. 1. The GameMode block runs every frame (60 times/sec) for as long as the scripted object's 3D is loaded. That is why the message is shown repeatedly. 2. SM01Sniper is a base form. You need to use the reference ID (or a ref variable storing it) when running functions on references. SM01Sniper.GetSelf is, therefore, not a valid statement. When you want to retrieve the reference of the actor running the script, simply use GetSelf without any prefix. 3. You need to use format specifiers when you want to display values with Message(Box)Ex. See the wiki page I directed you to in your other post.For example:MessageEx "Weapon Max Range %g" WeapMaxRangeMessageEx "Sniper %n" rSniper Finally, test the following script and see if it does the job for you. scn SniperModScript ref rSniper short bEngaging begin GameMode if rSniper == 0 set rSniper to GetSelf elseif bEngaging != (GetDistance player < 8000) set bEngaging to (bEngaging == 0) if bEngaging UseWeapon WeapNVGhillieSniperRifle rSniper player -1 1 0 elseif GetCurrentAIPackage == 33 RemoveScriptPackage EVP endif endif end Link to comment Share on other sites More sharing options...
irswat Posted March 10, 2014 Author Share Posted March 10, 2014 lol JIP! I knew my script was inefficient, but that inefficient? Yikes I'm rustier than I thought. Hehe Link to comment Share on other sites More sharing options...
irswat Posted March 10, 2014 Author Share Posted March 10, 2014 (edited) 30k game units away is not practical, considering:A. The maximum range of projectiles is 10k units.B. Most objects are not even loaded in memory when farther than ~12k units from the player. I did realize this so I changed the value to the Maximum range of the weapon. I would like to get the snipers to engage at the furthest distance away possible. The OnLoad segment of my script that adds the snipers to a Form List was to only apply the script to snipers loaded in memory. This was my first script I wrote for new vegas so please forgive the stupid mistakes, syntax errors, and inefficiencies. 1. The GameMode block runs every frame (60 times/sec) for as long as the scripted object's 3D is loaded. That is why the message is shown repeatedly. Actually it was the opposite. The debug message was only showing up once, and none of the other messages were showing up. 2. SM01Sniper is a base form. You need to use the reference ID (or a ref variable storing it) when running functions on references. SM01Sniper.GetSelf is, therefore, not a valid statement. When you want to retrieve the reference of the actor running the script, simply use GetSelf without any prefix. Good to know. I wonder why this wasn't throwing errors when I compiled it. This actually fixed the problems I was having! 3. You need to use format specifiers when you want to display values with Message(Box)Ex. See the wiki page I directed you to in your other post.For example:MessageEx "Weapon Max Range %g" WeapMaxRangeMessageEx "Sniper %n" rSniper I did see this but was confused by it. I didn't see the section where it listed the various format specifier types. Thanks. Finally, test the following script and see if it does the job for you. scn SniperModScript ref rSnipershort bEngaging begin GameMode if rSniper == 0 set rSniper to GetSelf elseif bEngaging != (GetDistance player < 8000) set bEngaging to (bEngaging == 0) if bEngaging UseWeapon WeapNVGhillieSniperRifle rSniper player -1 1 0 elseif GetCurrentAIPackage == 33 RemoveScriptPackage EVP endif endif endI'll test it out. I didn't expect you to do this for me. Thanks mate. I can't believe how much more efficient your code is then mine hehe. If it works I shall rename it to JIPSSnazzySniperModSCRIPT. I owe you a beer someday, in this life or the one to come hehe edit: No such luck. Snipers reacted around the 2000 unit mark. Edited March 11, 2014 by irswat Link to comment Share on other sites More sharing options...
irswat Posted March 10, 2014 Author Share Posted March 10, 2014 (edited) well the script you wrote didn't really do anything, but your point about SMSniper01.GetSelf being the wrong syntax fixed some of the problems! My debugs are working correctly, snipers [were] aiming and shooting (but not hitting [before I "optimized") from a much greater distance than previously, and the snipers are added and removed from the formlist.I'm gonna try tweaking the combat style like you suggested to get the sniper to shoot to kill everytime. Once that works I'm going to try to optimize the code.Are you familiar with something similar to a C++ For...While Loop in Geck? (edit nevermind I found this) This is supposed to be a more optimized version of the code. For some reason the distance (hfPlayer) never updates even when I move closer, and I get the debug message "Player is within range. Firing." but the Sniper never fires. I'm still not seeing these guys react from 8000-11000 units away as they are supposed to. I'm lucky if they react 3000 units away which makes the entire mod pointless. scn SniperModScript float hfPlayer=0 int AlertFlag=0 ref rSniper=00000000 begin GameMode ;debugging message MessageEx "Sniper Mod Debug Game Mode" ;sets sniper refID set rSniper to GetSelf MessageEx "Sniper refID %i" rSniper if (rSniper.GetDead == 0) set hfPlayer to player.GetDistance rSniper MessageEx "Distance away %g " hfPlayer endif elseif (rSniper.GetDead == 1) MessageEx "Sniper %i is dead" rSniper set hfPlayer to -72 endif if hfPlayer <= 11000 if (hfPlayer != -72) set AlertFlag to 1 endif endif elseif hfPlayer > 11000 set AlertFlag to 0 MessageEx "Player out of range by %g units." (hfPlayer-11000) endif if (AlertFlag == 1) if (player.GetDead == 0) ;Look rSniper ;rSniper.Look player MessageEx "Player within range. Firing." rSniper.UseWeapon WeapNVGhillieSniperRifle rSniper player 6 0 0 1 0 endif if (player.GetDead == 1) set AlertFlag to 0 endif endif end Edited March 11, 2014 by irswat Link to comment Share on other sites More sharing options...
Recommended Posts