EPDGaffney Posted December 25, 2017 Share Posted December 25, 2017 So, I have an object script on an NPC that adds weapons and makes him heal himself when he's either been hit a certain number of times or he's been brought to half-health, and some stuff is dependent on the number of Stimpaks he has. I have a variable called Hits to track the hits, and it's updated via OnHit. I have another one called Stage. The idea is that during Stage 0, he behaves one way, Stage 1 another way, and so on, up to Stage 3. But I suspect that these variables aren't working. Can anyone confirm this? It updates them, as I can see with SV in the console, but I think the script is only checking the other conditions. See, when he has no Stimpaks left, the next OnHit puts him at Stage 2, when he is given 25 throwing knives and the Stage is updated to 3. At this point, I don't want the script to do anything else. But every time I hit him, he gets 25 knives, so he has hundreds of knives by the end of the fight. I just want him to throw the 25 and then go back to chasing down the player for close-range combat. That's the end of the script. I really don't know what I'm doing wrong, but thinking about it, it must be using the other variablesin checks because he doesn't get 25 knives until he has no Stimpaks, which is technically not even part of the check for the 25 knives, but Stage is. begin onhit if GetItemCount Stimpak == 0 Set Stage to 2 endif end begin onhit if Stage == 2 AddItem GSBViperThrowingKnife 25 Set Stage to 3 endif endOr the whole script if you like: scn GSBViperOverlordScript Int Hits Int Stage begin onhit if Stage == 0 If GetHealthPercentage <= .5 AddItem GSBViperThrowingKnife 5 Set Stage to 1 Set Hits to 0 endif endif end begin onhit if Stage == 0 Let Hits += 1 If Hits >= 50 AddItem GSBViperThrowingKnife 5 Set Stage to 1 Set Hits to 0 endif endif end begin onhit if Stage == 1 Let Hits += 1 If Hits >= 10 If GetItemCount GSBViperThrowingKnife == 0 AddItem GSBViperThrowingKnife 5 Set Hits to 0 endif endif endif end begin onhit if Stage == 1 If GetHealthPercentage <= .5 If GetItemCount GSBViperThrowingKnife == 0 AddItem GSBViperThrowingKnife 5 Set Hits to 0 endif endif endif end begin onhit if GetHealthPercentage <= .5 if GetItemCount Stimpak > 0 EquipItem Stimpak endif endif end begin onhit if GetItemCount Stimpak == 0 Set Stage to 2 endif end begin onhit if Stage == 2 AddItem GSBViperThrowingKnife 25 Set Stage to 3 endif end Begin OnHit Player If GetDistance Player >= 3000 AddScriptPackage GSBRunToPlayer EndIf End Last thing, SV says there are no variables but then tells me the variables. What? Forgot to google that. Have to have a look. Link to comment Share on other sites More sharing options...
dubiousintent Posted December 25, 2017 Share Posted December 25, 2017 (edited) "OnHit" is a Block. Without an "ActorID", the block applies when hit by anyone. I have understood it that you can only have one of a particular block type (i.e. "hit by anyone") in any given script. Not clear why you think you need separate instances of the same block type in the first place. Why not nested conditions? Processing is more efficient if you group various dependent conditions under the same primary condition: e.g. one "IF Stage == 0" followed by the various other conditionals dependent upon that primary condition being true. -Dubious- Edited December 25, 2017 by dubiousintent Link to comment Share on other sites More sharing options...
EPDGaffney Posted December 25, 2017 Author Share Posted December 25, 2017 (edited) I want this to occur when he's hit by anyone. You can have as many of a blocktype as you want and in many cases I've found it to be not necessarily more efficient but to tell the engine to process something separately and thus make it less likely to call two things simultaneously when they shouldn't. I don't know for absolute certain that this is foolproof or if it just accidentally delays the engine enough to separate the calls, but it's worked where I've needed it. As for why I've done it here however, it was just one of a million things I've tried to get this to work. It was initially a much shorter script with && and || expressions and mostly in a single block. Breaking it up did improve some aspects of the way he behaves actually, though again, I'm not really sure that's an intentional feature of the engine, and it probably isn't a good thing to depend on. Edit:I've fixed this by changing the logic slightly: begin onhit if GetItemCount Stimpak == 0 if Stage == 1 AddItem GSBViperThrowingKnife 25 Set Stage to 2 endif endif endUnless something is off that I can't see, it should have worked before as well. The script initially ran this all as one check when I started having this problem, so it's not that I've condensed it somewhat that's fixed it. The major differences between the new code and what it looked like before are that I'm using 3 stages instead of 4 now, and I've changed the variables from Int to Short, though I'm not sure what bearing the latter has on this if any. I'm entertaining the idea that it's an engine quirk and not an error in my coding, but would love some confirmation. I'd like to experiment with condensing the code some more with fewer Begin blocks and more nested conditions (which is what it used to look like, mostly), but have to be careful as he was missing some checks that were being called simultaneously. Edited December 25, 2017 by EPDGaffney Link to comment Share on other sites More sharing options...
Recommended Posts