Jump to content

Object script ignoring one variable.


EPDGaffney

Recommended Posts

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
end

Or 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

"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 by dubiousintent
Link to comment
Share on other sites

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
end

Unless 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 by EPDGaffney
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...