Jump to content

Fallout New Vegas GECK & Scripting Help 101


Recommended Posts

Guest tomm434
Posted

I doubt it.

 

It only works with Say/SayTo so when SayTo finishes, it will run. It shouldn't run at other times.

 

Nice. Just don't understand what is causing this block to run. In theory there should always be a trigger that tells script to run. If this blocks doesn't check every frame that line is said, maybe that means that topic and npc object script become connected and Topic itself triggers NPC Object script.(yeah "it will be called as soon as line is completed")

 

I'm into that because I would like to  make many of these blocks, just don't want them slowing the game down.

Posted

I made a 'fake' SayToDone.  SayToDone can only be run from the script you assign to the individual NPC in the geck.  As Pride said.

 

Which imo, makes it pretty damn useless unless you want to edit vanilla assets.

Guest tomm434
Posted

I made a 'fake' SayToDone.  SayToDone can only be run from the script you assign to the individual NPC in the geck.  As Pride said.

 

Which imo, makes it pretty damn useless unless you want to edit vanilla assets.

 

You mean "Result script" field we talked about? Or something new?

 

 

Also there are nice commands

http://www.gribbleshnibit.com/projects/NVSEDocs/#GetScript

http://www.gribbleshnibit.com/projects/NVSEDocs/#SetScript

 

In theory we can store npc's object script and give him script we want(with SayToDone), then set him his old script again. But that's messy and risky, don't even want to get into that. Easy to spoil a savegame.

Posted (edited)

 

I made a 'fake' SayToDone.  SayToDone can only be run from the script you assign to the individual NPC in the geck.  As Pride said.

 

Which imo, makes it pretty damn useless unless you want to edit vanilla assets.

 

You mean "Result script" field we talked about? Or something new?

 

 

Also there are nice commands

http://www.gribbleshnibit.com/projects/NVSEDocs/#GetScript

http://www.gribbleshnibit.com/projects/NVSEDocs/#SetScript

 

In theory we can store npc's object script and give him script we want(with SayToDone), then set him his old script again. But that's messy and risky, don't even want to get into that. Easy to spoil a savegame.

 

 

Yep same thing we were talking about.

 

EDIT:  In my case I couldn't use the commands.  I'd need to add the script, run the script, remove the script every 0.? - 2 seconds for as long as sex is going on.  The commands should be viable though in other cases.  They just weren't for my purposes.

 

Edited by t3589
Posted

Is there a way to allow GECK to use more than 2 Gb of memory? it crashes far too much because it reaches the max... I've read on a forum to use that program that once was used even in FO3, I don't remember the name but the icon was some sort of red jalapeno pepper, it was supposed to increase the max memory. But it seems not working and it still crashing at 2 Gb... -_-

 

EDIT: nevermind, it seems that laa deflagged on its own for some obscure reason...

Posted

I've got maybe 26 conditions I need to check before saying that a reference is okay (they're each paired, so it's 13 pairs of conditions).  Is there a suggested way to go about this?  Use if/elseif for a bit, doing them maybe 5 pairs at a time?

 

I could do the 13 pairs separately.  I'm just looking to optimize.

 

((A AND B ) || (C AND D) || ....(X AND Y))

Posted

There is a limit to the number of clauses you can have in an if-elseif block, I think it is 16 or ~20. I believe the GECK PU throws an error if you reach it.

int Valid
let Valid := True
if MyMostCommonlyInvalidCondition
    let Valid := False
elseif MySecondMostCommonlyInvalidCondition
    let Valid := False
....
elseif TheLastConditionICanFit
   let Valid := False
endif
 
if Valid == False
    ; Pass
elseif TheNextConditionIWantToCheck
    let Valid := False
.....
Posted

Good deal.  Perhaps I will try to be fancy.  Perhaps I shall just split up the statements.

 

Hopefully one last question (feel like I'm hitting my quota for the day).

 

Equippable Flowers:  On adding an organic (not actual damaging weapon) flower, a token is added.  That token tracks the next 24 hours.  Once 24+ hours have passed, the flower and token are removed from the inventory.

 

I can account for it staying in the player's inventory, being sold, or being given to an NPC through dialogue.  How should I handle OnDrop so that the legitimately timed token is also removed?  Is this where array fanciness should come into play for the player?  Leave the token for NPCs only, and record the time + 24 hours to an array for the player.  OnDrop, if the current time < the purchase + 24 hour time, remove the first cell of the array so that all of the other next times shift down to the starting spot?

 

The token uses removeitem on the flower.  That's where the concern comes from...since the flower and token are in inventory, so they don't have a specific reference.  Maybe I'm making this harder than it is.  My brain has the fuzzy today.

 

I think it's kind of like your tracking food to figure out when it has spoiled issue, Odessa. 

Posted

On the max number of not nested if-else clauses you can have: I just counted and I have a block of 40 in one of my scripts that works fine. I just tested and I can compile a test script with over 700, eventually I hit the script length error but none about the if-else-block

 

However, I thought I hit a compile error once upon time with ~20, so I speculate that either NVSE4 allows more or the limit is more complex than just the number. Or, maybe I was paranoid back then and misblamed it on that.

Posted

1 block of 40 non-nested if/elseifs checking a single condition; variable 'iStage', with the final 'else' incrementing it.

 

Jaam commented that the language does not shortcut eval lines.

 

From which I infer that its technically more efficient to split them up like:

 

if cond1

  ; do X

elseif cond2

  ; do X

 

than

 

if cond1 || cond2

  ; do X

 

--

Although, I would be shocked if the performance benefit from skipping one or two unnecessary conditions is significant (as in effectively non-zero) unless they involves some complex UDF or checking a huge array. Splitting the lines is probably justified on readability anyway though.

 

=====

 

On the flower, adding a token along with the item sounds like a good idea, I didn't think of that. I believe a token can remove itself with 'RemoveMe' and that is the only way to remove a particular item from an inventory stack. Perhaps OnDrop/etc always drops the oldest one. I haven't thought this out much but what if:

 

- create a function which returns a unique int

- Flower OnAdd, add also a scripted token, which calls the function to get a unique ID for it, and use that as a key to a map array in some quest script.

- Flower OnDrop/etc, your map array moves (or something) the oldest to another array,

- Token GameMode notices that its been removed from array and RemoveMe it

 

I think you can set the ID on the actual flower during OnDrop and that will persist for use in a subsequent OnAdd, then if you pick it back up again it uses that ID instead of getting a new unique one.

 

...Well, maybe something along these lines would work?

Posted

I think you can set the ID on the actual flower during OnDrop and that will persist for use in a subsequent OnAdd, then if you pick it back up again it uses that ID instead of getting a new unique one.

 

And what happen if another reference from that same esp spawns in the meantime? shouldn't take the same ref because it's some sort of progressive number? well I don't know what the esp contains so mine it's just a curiosity :)

 

Sorry but probably I don't get the point of boths of you. What's the point in tracking all the tokens attributed to all the flowers to check the old one, when you can simply track the dates when you bought? How can I explain... Game-wise speaking, if you drop the oldest flower or you drop the newest flower, you simply remove FlowerID, you don't really need to know which one is oldest if they stack when you add more of them in the inventory. Different case if you want them appearing as two different items (fresh flower and old flower), at that point, still, you don't need to understand which reference is the new and the one, you just remove one new and add one old to the inventory. Isn't much or less what happens when vanilla items stack? when the game "sometimes" confuses which one you want to drop, because essentially they have no distintion?

 

Another way I could think about would be done without tokens and maybe finding a way to use their health as time, if there's a way for a spell to damage it with time, I never tried it.

 

About  if then statements, personally I started to nest everything and rarely use two on more checks in the same line. I put the less probable condition on top and the next ones after, concerning probability. And when I must check if it's false, I use else. I took this habit when I've read that in big numbers of cycles that was more efficent

if A
   if B
      if C

with A less probable than B, less probable than C

 

or if it must be false

if A
else B
Posted

Using health to track age is a cool idea. I wonder if that would work for me with ingestibles, I know the game doesn't officially support it, but I think it may be worth a try.

 

---

 

If I make the player playidle then actors can't start conversation with her until its finished, is there a way to end an idle early, aside from doing 'pushactoraway'?

Posted

I know that weapon health has been suggested to track a specific item.

 

I don't know if I can suggest the token to keep track for stacks.  My game shit itself when I purchased a huge stack of them yesterday (so that I had 20-30 something in my inventory).  Granted, I don't have a Timer in the script (part of it is forcing an NPC to equip the flower for 24 hours but unequip it if they get into combat).  Definitely fine for an NPC with 1 token.  Maybe less so with the player.  Needs more investigation as that I went into the GECK because I had other things to fix first.

 

For me, the specific item doesn't matter.  It probably wouldn't matter for Odessa either (guessing).  I think we can assume that the player would get rid of the salisbury steak that is the smelliest and leakiest.  :D

 

Need to reread your responses later when I get back to work.

 

For the long if statements (note:  get into the habit of if eval), I've grouped it more or less as well as I can, I think.  Checks if the player allows the PC to have sex with creatures.  The problem is then it has to go "is it a supermutant, and are supermutants allowed?  is it a feral ghoul, and are those allowed?..."   That's where the 13 pairs of conditions come in.

Posted

Sounds very similar to SexAssault, SexAssaultRRQuest has a big condition check for each actor in a scanner...

 

 

 

 ;=====Scan for Potential Victims and Rapist=====
    let rActor := GetFirstRef 200, 1
        
    while rActor != None

        ;DebugPrint "SA: RR - checking actor %n", rActor
        let iCanBeRapist := True
        let iCanBeVictim := True

        let rEqItem := rActor.GetEqObj 2

        ;=====Sexout Flag Check=====
        ;let iAV := rActor.GetAV Variable04
        if eval (call fnSexoutActorInUse rActor) ;.NX_GetEVFo "Sexout:Start::spellTarget"
            ;DebugPrint "SA: RR - Skipping %n, sexout in use", rActor
            rActor.NX_SetEVFl "SA:fNextStalkCheck", fNextCheck
            let iCanBeVictim := False
            let iCanBeRapist := False
        endif
        
        if ListGetFormIndex SexoutListBannedActor rActor > NotFound || ListGetFormIndex SexoutSLActorDataIsReserved rActor > NotFound
            ;DebugPrint "SA: RR - Skipping %n, in banned actor list", rActor
            let iCanBeRapist := False
            let iCanBeVictim := False
        endif

        ; ** Check if actor is already covered
        let iFind := Ar_Find rActor, arVictims
        if iFind > NotFound || rActor.IsSpellTarget SexAssaultRapistSpell
            ;DebugPrint "SA: RR - Skipping %n, already a victim or rapist" rActor
            let iCanBeRapist := False
            let iCanBeVictim := False
        else
            ; ** Sometimes, the package doesnt get removed when stalk spell does, for some reason
            if rActor.GetCurrentPackage == SexAssaultStalkPlayer
                rActor.RemoveScriptPackage SexAssaultStalkPlayer
            elseif rActor.GetCurrentPackage == SexAssaultStalkMark1
                rActor.RemoveScriptPackage SexAssaultStalkMark1
            elseif rActor.GetCurrentPackage == SexAssaultStalkMark2
                rActor.RemoveScriptPackage SexAssaultStalkMark2
            elseif rActor.GetCurrentPackage == SexAssaultStalkMark3
                rActor.RemoveScriptPackage SexAssaultStalkMark3
            endif
        endif

        ;=====Potential Victim Check=====
        if iCanBeVictim == False
            ; Pass
        elseif rActor.GetDisabled || rActor.GetDead || rActor.GetUnconscious || rActor.GetKnockedState || rActor.IsChild
            let iCanBeVictim := False
        elseif rActor.GetIsCreature
            let iCanBeVictim := False
        elseif eval !(SexAssault.iTeamR) && rActor.GetPlayerTeammate
            let iCanBeVictim := False
        elseif eval !(SexAssault.iOthers) && !(rActor.GetPlayerTeammate)
            let iCanBeVictim := False
        elseif SexAssault.iPowerArmor && rEqItem.IsPA
            let iCanBeVictim := False
        elseif rActor.IsSpellTarget SexoutDualChastityEffect || rActor.IsSpellTarget SexoutChastityEffect
            let iCanBeVictim := False
        endif
            
        ;=====Potential Rapist Check=====
        if iCanBeRapist == False
            ; Pass
        elseif fCurrentTime < rActor.NX_GetEVFl "SA:fNextStalkCheck"
            ;DebugPrint "SA: RR - Skipping %n, is cooling down", rActor
            let iCanBeRapist := False
        elseif rActor.GetDisabled || rActor.GetDead || rActor.IsChild
            ;DebugPrint "SA: RR - Skipping %n, is disabled/dead/child", rActor
            let iCanBeRapist := False
        ; *** Check if actor will attack player, since stalk won't work in combat.
        ; *** unless target is different relation := player, but this is rare since any time
        ; *** player is around, they'll start combat anyway
        elseif rActor.GetFactionRelation PlayerREF < 2 && rActor.GetAV Aggression > 1
            ;DebugPrint "SA: RR - Skipping %n, is player enemy", rActor
            let iCanBeRapist := False
        ; *** Stalking doesn't start via the spell effect until a victim is detected. Otherwise it just cools down
        ; *** If the player isnt detected then probably no victims are, and even if so, its a waste of time
        ; *** if they can't see it.
        elseif eval !(rActor.GetDetected PlayerREF) && (rActor.GetDistance PlayerREF > 1000)
            ;DebugPrint "SA: RR - Skipping %n, has not detected player", rActor
            let iCanBeRapist := False
        elseif rActor.GetUnconscious || rActor.GetKnockedState
            ;DebugPrint "SA: RR - Skipping %n, unconscious or knocked", rActor
            let iCanBeRapist := False
        elseif rActor.GetPlayerTeammate
            ;DebugPrint "SA: RR - Skipping %n, is player team mate", rActor
            let iCanBeRapist := False
        ; ** Soliciting, only nasty NPCs stalk. Only previously solicited NPCs have this NX.
        elseif rActor.NX_GetEVFl "Sexout:iDisposition" > 1
            let iCanBeRapist := False
        elseif rActor.NX_GetEVFl "Sol:Disposition" > 1
            let iCanBeRapist := False
        elseif SexAssault.iKarma && rActor.GetAv Karma >= 500
            ;DebugPrint "SA: RR - Skipping %n, karma with MCM option", rActor
            let iCanBeRapist := False
        elseif rEqItem != None
            if rEqItem.IsPA && SexAssault.iPowerArmor
                ;DebugPrint "SA: RR - Skipping %n, is wearing Power Armor", rActor
                let iCanBeRapist := False
            endif
        endif
            
        ;===== Race Checks =====
        if iCanBeRapist == False
            ;DebugPrint "SA: RR - %n can't rape 2" rActor
            ; Pass
        elseif eval !(rActor.GetIsCreature)
            ; ** Check if MCM options allow
            if eval !(SexAssault.iGhouls) && rActor.GetIsRace Ghoul
                ;DebugPrint "SA: RR - Skipping %n, No Ghouls MCM", rActor
                rActor.NX_SetEVFl "SA:fNextStalkCheck" fNextCheck
                let iCanBeRapist := False
            elseif eval !(SexAssault.iHumans)
                ;DebugPrint "SA: RR - Skipping %n, no humans MCM", rActor
                rActor.NX_SetEVFl "SA:fNextStalkCheck" fNextCheck
                let iCanBeRapist := False
            elseif ItIsDayTime && GetRandomPercent < 75
                DebugPrint "SA: RR - Skipping %n until night time", rActor
                rActor.NX_SetEVFl "SA:fNextStalkCheck" fNightTime
                let iCanBeRapist := False
            endif
        elseif eval !(SexAssault.iAnimals) && ( rActor.GetIsCreatureType 0 || rActor.GetIsCreatureType 1 )
            let iCanBeRapist := False
        elseif eval !(SexAssault.iInsects) && rActor.GetIsCreatureType 2
            let iCanBeRapist := False
        elseif eval !(SexAssault.iCreatures) && ( rActor.GetIsCreatureType 3 || rActor.GetIsCreatureType 7 )
            let iCanBeRapist := False
        elseif rActor.GetIsCreatureType 6 || rActor.GetInFaction BrahminFaction
            let iCanBeRapist := False ; * Brahmin + Robots have no sexout anims
        elseif eval !(SexAssault.iMutants) && rActor.GetIsCreatureType 4
            let iCanBeRapist := False
        elseif eval !(SexAssault.iFeralGhouls) && rActor.GetIsCreatureType 5
            let iCanBeRapist := False
        elseif SexAssault.rOWBRobotFaction != None ; * No anims
            let rFaction := SexAssault.rOWBRobotFaction
            if rActor.GetInFaction rFaction
                let iCanBeRapist := False
            endif
        endif


        if iCanBeRapist == False && iCanBeVictim == False
            ;DebugPrint "SA: RR - %n not a (new?) rapist or victim" rActor
            let rActor := Pencil01
            let rActor := GetNextRef
            continue
        endif
            
        ;=====Optional Faction Checks=====
        if rActor.GetIsCreature
            let fChanceMultiplier := SexAssault.fCreatureMult
        elseif rActor.GetInFaction VCaesarsLegionFaction
            let fChanceMultiplier := SexAssault.fLegion
        elseif rActor.GetInFaction KingsFaction
            let fChanceMultiplier := SexAssault.fKings
        elseif rActor.GetInFaction NCRFactionNV
            let fChanceMultiplier := SexAssault.fNCR
        elseif rActor.GetInFaction GreatKhansFactionNV
            let fChanceMultiplier := SexAssault.fKhans
        elseif rActor.GetInFaction FiendsFactionNV
            let fChanceMultiplier := SexAssault.fFiends
        elseif rActor.GetIsClass PowderGanger
            let fChanceMultiplier := SexAssault.fPowder
        elseif rActor.GetInFaction BoomerFaction
            let fChanceMultiplier := SexAssault.fBoomers
        else
            let fChanceMultiplier := SexAssault.fOtherMult
        endif

        if fChanceMultiplier == 0
            rActor.NX_SetEVFl "SA:fNextStalkCheck", fNextCheck
            let iCanBeRapist := False
        endif
            

        if iCanBeRapist == False && iCanBeVictim == False
            ;DebugPrint "SA: RR (2) %n not a (new) rapist or victim" rActor
            let rActor := Pencil01
            let rActor := GetNextRef
            continue
        endif
            
        ;====Creature Cum Smell Offsets====
        if rActor.GetIsCreature
            if rActor.GetIsCreatureType 5 && ( PlayerREF.IsSpellTarget SexoutSEFFCumVagFeralGhoul || PlayerREF.IsSpellTarget SexoutSEFFCumVagGhoulM )
                let fChanceMultiplier *= 2
            elseif rActor.GetInFaction SporePlantFaction && PlayerREF.IsSpellTarget SexoutSEFFCumVagSpores
                let fChanceMultiplier *= 3
            elseif rActor.GetInFaction VCrCazadorFaction && PlayerREF.IsSpellTarget SexoutSEFFCumVagCazador
                let fChanceMultiplier *= 2
            elseif rActor.GetInFaction CreatureHitDog && PlayerREF.IsSpellTarget SexoutSEFFCumVagDogM
                let fChanceMultiplier *= 1.5
            elseif rActor.GetInFaction VCrBigHornerFaction && PlayerREF.IsSpellTarget SexoutSEFFCumVagBigHorner
                let fChanceMultiplier *= 1.5
            endif
        endif
        if eval ( (PlayerREF.GetEqObj 2) == None ) ; * Naked
            let fChanceMultiplier *= 1.25
        endif
        if SexAssault.iConcede
            let fChanceMultiplier *= 1.5
        endif
        let iRand := GetRandomPercent
        let iFinalChance := SexAssault.fRandomRape * fChanceMultiplier
        if iCanBeRapist && iRand > iFinalChance
            DebugPrint "SA: RR - %n is not a stalker - Roll: %g > Chance: %g  (Multiplier was %0.2f)" rActor iRand iFinalChance fChanceMultiplier
            rActor.NX_SetEVFl "SA:fNextStalkCheck", fNextCheck
            let iCanBeRapist := False
        endif
            
        ;=====Cast Rapist or Victim Spell=====
        if iCanBeRapist
            DebugPrint "SA: RR - %n is now a Stalker (iFinalchance: %g)", rActor, iFinalChance
            rActor.CIOS SexAssaultRapistSpell
        elseif iCanBeVictim
            Ar_Append arVictims rActor
            DebugPrint "SA: %n is a now a potential victim", rActor
        endif
            
        let rActor := Pencil01
        let rActor := GetNextRef
    loop ; * check next actor

 

 

 

Creatures are checked in the 6th block of if-elseifs..

 

...Kind of ugly.

Guest tomm434
Posted

Ok Nyaalich,I don't understand what exactly conditions do but you might condider using arays. You can make 2 arrays and loop the code.
Also I didn't check that and I have no idea if that works xDD. Actualy it was A.J's code  but I think I changed it to your purpose.

array_var NPCFaction
array_var FactionCheck
int CurrentCheck (returns if NPCref is in current faction. Current faction is determined by "slotnumber")
int faction (returns check value for current faction. Current Check is determined by "slotnumber2")
int slotnumber
int slotnumber2


let Faction := ar_List GhoulFaction, SuperMutantFaction, etc
let FactionCheck := ar_List "yourquest.yourcondition1 for Ghouls", "yourquest.yourcondition2 for Mutants"


                let CurrentCheck := NPCref.getinfaction NPCFaction[slotnumber]
                let Faction := FactionCheck[slotnumber2]

                 label 1

                    if CurrentCheck == Faction
                        let slotnumber :=XX(to end scanner)
                    else
                        let slotnumber +=1
                        let slotnumber2 +=1
                    endif

                    if slotnumber >= XX
                            Proceed forward
                        else
                            goto 1



endif

it's a simple loop. Don't know if this would be faster but it sure looks more beautiful.

 

 

More explaining

 

if CurrentCheck == Faction

 

Current Check will return either 0 or 1

 

Faction is a variable from your script. I don't know your system but something tells me that it has 2 options - 0 or 1 (allow or not). So, if actor is included in faction(==1) and this variable is equal to your check (==1 to), then you can proceed. Tell me what you think.

 

Posted

Nice thinking, on that note, you could also do:

ref ActorRace
 
let ActorRace := rActor.GetRace
 
if eval Ar_Find MyListArrayOfPermittedRaces, ActorRace != Ar_BadNumericIndex
    ; proceed
else
   ; not allow
endif

Simply add/remove allowed races to an array, and check that.

Posted

For the long if statements (note:  get into the habit of if eval), I've grouped it more or less as well as I can, I think.  Checks if the player allows the PC to have sex with creatures.  The problem is then it has to go "is it a supermutant, and are supermutants allowed?  is it a feral ghoul, and are those allowed?..."   That's where the 13 pairs of conditions come in.

 

As I said I rarely use conditions in a row. Sometimes of course I still need them, it depends by the case, but as you wrote up here I can sum up in this way:

if is supermutant
  if is allowed

elseif is ghoul
  if is allowed

else
return

About if eval, I remember jaam writing that if eval checks all the block of statements even if the first returns false (I could have misunderstood of course), that would spoil my purpose for optimization. I must run heavy code in no time, that's essential for me.

 

EDIT: just to clarify a bit. My assumption is it skips false conditions when it runs, so my goal is keeping the less number of conditions per frame / per case.

i.e.

if ((is supermutant ) && (is allowed)) || ((is ghoul) && (is allowed)

total evaluations: 4, every frame.

 

my previous example:

if it's supermutant or ghoul and it's allowed: 2/3 evaluations

 

of course I can have misunderstood everything since I don't know the engine below and I don't want to test the timing of these scripts, and maybe it evaluates everything like if eval...

Posted

That's "If" doing not only "if eval". :)

What eval does is evaluate the whole remaining line and not only the part you decided it should eval.

 

Posted

That's "If" doing not only "if eval". :)

What eval does is evaluate the whole remaining line and not only the part you decided it should eval.

if is_supermutant
  if is_allowed
    ;do code
  else
    return
  endif
else
  return
endif

So do you mean that the engine will waste time checking if "it_allowed" even if is_supermutant returns false?

That's very important for me to understand this, so at least I can see if rewriting scripts in a more readable way

Posted

no.

It means that if you write:

 

  if is_supermutant && is_allowed

 

is_allowed will be evaluated even if is_supermutant is false.

 

Posted

Thanx. I misunderstood your statement ("the language does not shortcut the evals. It will calculate everything even if it already knows the final value.") thinking that eval was the difference.

Good to know that at least this abstruse nesting is useful to something

Posted

Odessa's checking by GetIsCreatureType (forgot that fxn existed), whereas I'm checking the SO form list for each creature.  Perhaps the easiest thing would be condense it to one form list of banned creature type form lists, check if the creature is in it, and if not, check the variable to see if Other Creatures types (ones added by other mods) are allowed.

 

Also, thanks, jaam, on the IF EVAL thing.  Excellent ideas all around, everyone.  ^5

Posted

If anyone's curious, this is what I ended up doing for the script.  Granted, it hasn't been tested in game.  Unfortunately, because "other" creatures do use two of the existing anims, I had to create 2 form lists to track allowed and off-limits creatures so that all existing creatures could be checked before seeing if other ones are permitted by the player.

 

It hasn't been verified in game as that I need to rework the fuck out of my MCM script to take the form lists into account.

 

Question:  Does ListRemoveForm generate an error/explode if the given form IS NOT in the list, or does it just shrug?

 

 

 

scn SexoutBangFXNIsValidTargetSCRIPT

ref rPartner

int iIsTargetValid
int iSexoutValidRef

Begin Function{rPartner}
	Set iSexoutValidRef to Call fnSexoutActorInuse rPartner
	if (((0 == iSexoutValidRef) || (1 == iSexoutValidRef)) && (0 == rPartner.GetDead) && (0 == rPartner.GetDisabled) && (0 == rPartner.IsChild) && (0 == rPartner.GetUnconscious) && (0 == rPartner.GetKnockedState) && (0 == NX_IsInList SexoutBannedActorsWithPlayer rPartner)&& (0 == NX_IsInList SexoutListBannedActor rPartner))	
		if ((1 == rPartner.getisrace ghoul) && (1 == SexoutBangMain.iGhouls))||((0 == rPartner.getisrace ghoul) && (1 == SexoutBangMain.iHumans))
			Let iIsTargetValid := 1
			DebugPrint "Bangatron_FXNIsValidTarget: rPartner %i is Humanoid" rPartner			
		elseif ((1 == rPartner.GetIsCreature) && (1 == SexoutBangMain.iAllowCreatures))
			if (0 < NX_IsInList SexoutBangAllowedCreatures rPartner)
				Let iIsTargetValid := 1
				DebugPrint "Bangatron_FXNIsValidTarget: rPartner %i is Allowed Creature" rPartner
			elseif (0 < NX_IsInList SexoutBangOffLimitsCreatures rPartner)
				DebugPrint "Bangatron_FXNIsValidTarget: rPartner %i was an off-limits creature" rPartner
				Let iIsTargetValid := 0
				Set SexoutBangMain.iStage to 0
			elseif (SexoutBangMain.iOther)
				Let iIsTargetValid := 1
				DebugPrint "Bangatron_FXNIsValidTarget: rPartner %i is Allowed Other Creature" rPartner
			else
				DebugPrint "Bangatron_FXNIsValidTarget: rPartner %i is an Other Creature and not allowed" rPartner
				Let iIsTargetValid := 0
				Set SexoutBangMain.iStage to 0		
			endif
		else
			DebugPrint "Bangatron_FXNIsValidTarget: rPartner %i was not an allowed NPC or was a creature with creatures off" rPartner
			Let iIsTargetValid := 0
			Set SexoutBangMain.iStage to 0
		endif
	else
		DebugPrint "Bangatron_FXNIsValidTarget: rPartner %i failed standard checks" rPartner
		Let iIsTargetValid := 0
		Set SexoutBangMain.iStage to 0
	endif
	Return iIsTargetValid
End

 

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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