Jump to content

Using setav on Confidence in an object script causes crashes.


CountFuzzball

Recommended Posts

I have an object script that sets a bunch of variables to an NPCs starting behaviour:

 

if statsChanged == 0
if target.HasMagicEffect MS13Mezzed == 0
; don't change stats until mezzed effect goes away, to make sure we're looking at REAL stats

; There might be a massively bad race condition here! :/

set statsChanged to 1

set StartingAggression to target.getAv Aggression
set StartingAssistance to target.getAv Assistance
set StartingConfidence to target.getAv Confidence
set StartingEnergy to target.getAv Energy
set StartingResponsibility to target.getAv Responsibility
set StartingMood to target.getAv Mood
set StartingIgnoreCrime to target.getignorecrime
endif
endif

 

Then sets it back again at the end of it:

 

target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime

 

The problem is, all of the other setAvs work, except for the setAv Confidence. Whenever that is run, it causes the game to crash. Any workarounds/fixes for this would be quite appreciated.

Link to comment
Share on other sites

I never did this for confidence, but did it for other stats. When I did, I used GetBaseAV to store the original stat and then SetAv to restore. It may be the case that the confidence has a modifier that is being added back twice by not storing the base. In other words, you are saving the modified value then restoring that value only to have it modified again and that puts the confidence value out of bounds.

 

Anyway, try using GetBaseAV and see if that fixes the issue.

 

 

EDIT: I see that you've ripped this script from the mezzed script where they used GetAv, so you would naturally think it should work regardless of needing GetbaseAV. That script was an effect script and yours is an object script, so there may be more going on than a simple code issue. Perhaps what is needed here is a bit more background on what is going on with the object and the NPC...maybe post your whole code and describe in detail what should be happening.

Edited by pkleiss
Link to comment
Share on other sites

I use SetAV confidence, assistance, and aggression very frequently in my companion mods with no issue (every combat cycle). One thing - you don't want to be setting Actor values every frame of an object script.
Maybe post your script to see what is going on.

These three values are a bit different from other actor values. I don't know what happens if you try to set them to invalid numbers. I guess the base value would be the value programmed in the NPC record, but I've never used it. Just GetAV and SetAV for these.
Value ranges:
confidence 0-4
assistance 0-2
aggression 0-2

Link to comment
Share on other sites

The only other script that might have a problem with what I'm doing is the MS13CollarEffect script (the only script that adds the CFPackageSlaveToken object with the CFSlaveTravelPackageScript script).

 

MS13CollarEffect:

 

 

 

scn MS13CollarEffectScript


;!!!!!!!!!!!!!!!!------------- the "don't dispel on death" flag in the Magic Effect form it needs to be marked so this script with work properly with the death on the actor ---------------!!!!!!!!!!!!!!!!!!!!!!!!

short arrived

short marked

short statsChanged ; set to 1 after Mezzed spell goes away and stats have been changed

; save original stats so we can restore them if collar removed
short StartingAggression
Short StartingAssistance
Short StartingConfidence
Short StartingEnergy
Short StartingResponsibility
Short StartingMood
short StartingIgnoreCrime

float alarmTimer

Begin ScriptEffectStart

set marked to 0

PFallsAdultPenGate.unlock

; get rid of mezzed spell
dispel MS13MezzedSpell

;add to a faction which is friends with the player so that I won't aggro on player even if he has a crime tracking faction that hates the player
addToFaction MS13CollarFaction 0
set StartingIgnoreCrime to GetIgnoreCrime
ignoreCrime 1

; make sure running correct packages
; CF: Keeps the slaves from traveling about the wastes when we fast travel.
if GetInCell PFallsSlaveHouse == 0 && getIsCurrentPackage MS13Enslaved == 0
AddScriptPackage MS13TravelToParadiseFalls
endif

if getitemcount CFpackageslavetoken < 1 ; CF: Probably should move this into the oneffectstart block
additem CFpackageslavetoken 1 ; CF: this can run "too fast".
endif

End

Begin ScriptEffectUpdate
if statsChanged == 0
if HasMagicEffect MS13Mezzed == 0
; don't change stats until mezzed effect goes away, to make sure we're looking at REAL stats
set statsChanged to 1

; save stats for VIPs in case they're rescued after arriving in PF
if GetIsID Red == 1 && MS13.RedStatsChanged == 0
set MS13.RedStatsChanged to 1
set MS13.RedAggression to getAv aggression
set MS13.RedAssistance to getAv assistance
set MS13.RedConfidence to getAv confidence
elseif GetIsID Flak == 1 && MS13.FlakStatsChanged == 0
set MS13.FlakStatsChanged to 1
set MS13.FlakAggression to getAv aggression
set MS13.FlakAssistance to getAv assistance
set MS13.FlakConfidence to getAv confidence
elseif GetIsID SusanLancaster == 1 && MS13.SusanStatsChanged == 0
set MS13.SusanStatsChanged to 1
set MS13.SusanAggression to getAv aggression
set MS13.SusanAssistance to getAv assistance
set MS13.SusanConfidence to getAv confidence
elseif GetIsID Arkansas == 1 && MS13.ArkansasStatsChanged == 0
set MS13.ArkansasStatsChanged to 1
set MS13.ArkansasAggression to getAv aggression
set MS13.ArkansasAssistance to getAv assistance
set MS13.ArkansasConfidence to getAv confidence
endif

set StartingAggression to getAv Aggression
set StartingAssistance to getAv Assistance
set StartingConfidence to getAv Confidence
set StartingEnergy to getAv Energy
set StartingResponsibility to getAv Responsibility
set StartingMood to getAv Mood

;set up AI data
if GetPlayerTeammate == 0
setAv Aggression 0
setAv Assistance 0
setAv Confidence 0
setAv Energy 5
setAv Responsibility 0
setAv Mood 4
endif

endif
endif

; send assault alarm after exiting dialogue
; use actor value so we make sure to only do this once
if getav variable09 == 0
if menumode == 0
set alarmTimer to alarmTimer + ScriptEffectElapsedSeconds
if alarmTimer > 2
setav variable09 9
SendAssaultAlarm
stopcombat
endif
endif
endif

; make sure running correct package
if GetItemCount MS13Collar < 1 ; No collar means we missed its removal, somewhere... so end the script
removeitem CFSlaveBook 1
removeitem CFpackageslavetoken 1
removeFromFaction MS13CollarFaction
RemoveFromFaction ParadiseFallsSlaveFaction
RemoveFromFaction FollowerFaction
if getIsCurrentPackage MS13TravelToParadiseFalls == 1
RemoveScriptPackage
endif
if getIsCurrentPackage MS13Enslaved == 1
RemoveScriptPackage
endif

ignoreCrime StartingIgnoreCrime

if GetIsID Red == 1 && MS13.RedStatsChanged == 1
set MS13.RedStatsChanged to 0
setav aggression MS13.RedAggression
setav assistance MS13.RedAssistance
setav confidence MS13.RedConfidence
elseif GetIsID Flak == 1 && MS13.FlakStatsChanged == 1
set MS13.FlakStatsChanged to 0
setav aggression MS13.FlakAggression
setav assistance MS13.FlakAssistance
setav confidence MS13.FlakConfidence
elseif GetIsID SusanLancaster == 1 && MS13.SusanStatsChanged == 1
set MS13.SusanStatsChanged to 0
setav aggression MS13.SusanAggression
setav assistance MS13.SusanAssistance
setav confidence MS13.SusanConfidence
elseif GetIsID Arkansas == 1 && MS13.ArkansasStatsChanged == 1
set MS13.ArkansasStatsChanged to 0
setav aggression MS13.ArkansasAggression
setav assistance MS13.ArkansasAssistance
setav confidence MS13.ArkansasConfidence
elseif statsChanged == 1
setAv Aggression StartingAggression
setAv Assistance StartingAssistance
setAv Confidence StartingConfidence
setAv Energy StartingEnergy
setAv Responsibility StartingResponsibility
setAv Mood StartingMood
endif
elseif GetPlayerTeammate == 1

elseif getIsCurrentPackage MS13TravelToParadiseFalls == 0 && getIsCurrentPackage MS13Enslaved == 0 && GetItemCount MS13Collar > 0
AddScriptPackage MS13TravelToParadiseFalls
endif

if arrived == 0
if getDead == 1 ; this only makes sense because the effect is marked not to be dispelled on death
if getitemcount CFSlaveIsDeadTOKEN == 0
additem CFSlaveIsDeadTOKEN 1
set arrived to -1
;if MS13Slaves.numSlaves == 0 ; CF: But this only works on the first slave captured. *bug fixed*
set MS13Slaves.slaveArrived to -1 ;(-1 = died)
;endif

GrouseRef.evp ;to get him walking to forcegreet the player
endif
elseif (getInCell ParadiseFallsExterior == 1 || GetInWorldspace ParadiseFalls == 1)
if getitemcount CFSlaveBook == 0
additem CFSlaveBook 1
;slave arrived on his own because he was a persistent actor, or a non-persistent actor who didn't unload (accompanied by the player)
set arrived to 1
if marked < 1
set MS13Slaves.numSlaves to MS13Slaves.numSlaves + 1
set marked to 1
endif

; add to slave faction so slavers react to player attacking
addToFaction ParadiseFallsSlaveFaction 0

;check to see if this is any of the named targets of MS13 and set the proper variable
if GetSelf == RedRef
if MS13.RedArrived == 0
set MS13.RedArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
elseif GetSelf == ArkansasRef
if MS13.ArkansasArrived == 0
set MS13.ArkansasArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
elseif GetSelf == FlakRef
if MS13.FlakArrived == 0
set MS13.FlakArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
elseif GetSelf == SusanLancasterRef
if MS13.SusanArrived == 0
set MS13.SusanArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
else
; only for generic slaves
set MS13Slaves.slaveArrived to 1 ;(1 = he arrived for real)
set MS13Slaves.arriveDay to gamedayspassed

if getitemcount CFpackageslavetoken < 1 ; CF: Probably should move this into the oneffectstart block
additem CFpackageslavetoken 1 ; CF: this can run "too fast".
endif
endif

GrouseRef.evp ;to get him walking to forcegreet the player

endif
endif
endif

; Only remove the slave once they've hung out in Paradise Falls for a day
; CF: Moved this into the CFSlaveTravelPackage script. Object scripts seem a better option for holding variable data stuff as they persist when
; the player leaves the object's cell and don't reset to 0 whenever the player re-enters the cell its in.

End


Begin ScriptEffectFinish
if MS13Slaves.debug == 1
ShowWarning "MS13CollarEffect -- ScriptEffectFinish"
endif

;This block will run if the spell is dispelled, which only happens when the NPC unloads (because the spell effect is marked not to dispell on death), of if the player removes the collar from the NPC
;--Except that's not true, because it can also happen during dialogs, or when you pause, or a thousand other things

if MS13Slaves.playerRemovedCollar == 1 || GetItemCount MS13Collar < 1
set MS13Slaves.playerRemovedCollar to -1

; reset stats back to original
removeFromFaction MS13CollarFaction
RemoveFromFaction ParadiseFallsSlaveFaction
RemoveFromFaction FollowerFaction
if getIsCurrentPackage MS13TravelToParadiseFalls == 1
RemoveScriptPackage
endif

set MS13Slaves.arriveDay to 0

ignoreCrime StartingIgnoreCrime

if GetIsID Red == 1 && MS13.RedStatsChanged == 1
set MS13.RedStatsChanged to 0
setav aggression MS13.RedAggression
setav assistance MS13.RedAssistance
setav confidence MS13.RedConfidence
elseif GetIsID Flak == 1 && MS13.FlakStatsChanged == 1
set MS13.FlakStatsChanged to 0
setav aggression MS13.FlakAggression
setav assistance MS13.FlakAssistance
setav confidence MS13.FlakConfidence
elseif GetIsID SusanLancaster == 1 && MS13.SusanStatsChanged == 1
set MS13.SusanStatsChanged to 0
setav aggression MS13.SusanAggression
setav assistance MS13.SusanAssistance
setav confidence MS13.SusanConfidence
elseif GetIsID Arkansas == 1 && MS13.ArkansasStatsChanged == 1
set MS13.ArkansasStatsChanged to 0
setav aggression MS13.ArkansasAggression
setav assistance MS13.ArkansasAssistance
setav confidence MS13.ArkansasConfidence
elseif statsChanged == 1
setAv Aggression StartingAggression
setAv Assistance StartingAssistance
setAv Confidence StartingConfidence
setAv Energy StartingEnergy
setAv Responsibility StartingResponsibility
setAv Mood StartingMood
endif
elseif GetInSameCell player != 1
;assume the NPC unloaded -- which we can only assume if they aren't in the same cell

;if the slave hasn't arrived yet, we'll fake it as if he did arrive when the player wasn't looking (he's not in the same cell as the player or he wouldn't have unloaded)
if arrived == 0
if getitemcount CFSlaveBook == 0
additem CFSlaveBook 1
set MS13Slaves.arriveDay to gamedayspassed
set arrived to 2
if marked < 1
set MS13Slaves.numSlaves to MS13Slaves.numSlaves + 1
set marked to 1
endif
set MS13Slaves.slaveArrived to 2 ;(2 = we faked his arrival)
; add to slave faction so slavers react to player attacking
addToFaction ParadiseFallsSlaveFaction 0

if GetSelf == RedRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.RedArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
elseif GetSelf == ArkansasRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.ArkansasArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
elseif GetSelf == FlakRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.FlakArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
elseif GetSelf == SusanLancasterRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.SusanArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
else
;it was someone else
set MS13Slaves.arriveDay to GameDaysPassed
GrouseRef.evp

if getitemcount CFpackageslavetoken < 1 ; CF: Probably should move this into the oneffectstart block
additem CFpackageslavetoken 1 ; CF: this can run "too fast".
endif
;moveto ParadiseFallsSlaveHouseMARKER
endif

;GrouseRef.evp ;to get him walking to forcegreet the player

endif
endif

endif

endif

End

 

 

 

 

CFSlavePackageTravelScript:

 

 

 

scn CFSlavePackageTravelScript
ref target
short statsChanged
short StartingAggression
Short StartingAssistance
Short StartingConfidence
Short StartingEnergy
Short StartingResponsibility
Short StartingMood
short StartingIgnoreCrime

begin gamemode

set target to getContainer

if target == 0
Return ; getContainer doesn't always work first time around.
else

if statsChanged == 0
if target.HasMagicEffect MS13Mezzed == 0
; don't change stats until mezzed effect goes away, to make sure we're looking at REAL stats
set statsChanged to 1

set StartingAggression to target.getAv Aggression
set StartingAssistance to target.getAv Assistance
set StartingConfidence to target.getAv Confidence
set StartingEnergy to target.getAv Energy
set StartingResponsibility to target.getAv Responsibility
set StartingMood to target.getAv Mood
set StartingIgnoreCrime to target.getignorecrime
endif
endif

if ((target.getDistance player > 100 && target.getInSameCell Player == 0) || target.getInSameCell Player == 0) && target.getincell pfallsslavehouse == 0 && target.GetItemCount MS13Collar > 0

;target.RemoveFromFaction MS13CollarFaction
;target.RemoveFromFaction ParadiseFallsSlaveFaction
;target.RemoveFromFaction FollowerFaction

if target.getInFaction WastelanderFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
target.moveto CFWastelanderMarkerREF ;-- Just stash the body somewhere if/until they respawn
elseif target.getInFaction RCSecurityFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
target.moveto CFRCSecurityMarkerREF ;-- Just stash the body until they respawn
elseif target.getInFaction RaiderFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
;target.setAv Confidence 4
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
target.moveto CFRaiderMarkerREF ;-- Just stash the body somewhere until they respawn
player.moveto CFRaiderMarkerREF
elseif target.getInFaction EnclaveFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
target.moveto CFEnclaveMarkerREF ;-- Just stash the body somewhere until they respawn
elseif target.getInFaction BrotherHoodOutCastFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
target.moveto CFWastelanderMarkerREF ;-- Just stash the body somewhere until they respawn
elseif target.getInFaction TalonCompany == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
target.moveto CFTalonMarkerREF ;-- Just stash the body somewhere until they respawn
elseif target.getInFaction BrotherHoodSteelFaction ==1 ; Or BrotherHoodSteelGenericFaction?
target.moveto CFWastelanderMarkerREF ;-- Just stash the body somewhere until they respawn
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
elseif target.getInFaction RegulatorFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
target.moveto CFRegulatorMarkerREF ;-- Just stash the body somewhere until they respawn
else ; generic npc
target.moveto ParadiseFallsSlaveHouseMARKER
target.AddScriptPackage MS13Enslaved
player.additem caps001 75
endif
endif

; CF: Need to move this block here so it always runs. After acquring numerous slaves, the scripteffectupdate block only runs on the last slave captured.
if MS13Slaves.arriveDay != 0 && ( GameDaysPassed - MS13Slaves.arriveDay > 1 ) && target.getincell pfallsslavehouse == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
;target.moveto FFEnclaveEncampmentMasterREF ;-- Just stash the body somewhere if/until they respawn
;CastImmediateOnSelf LaserDisintegrationFXSpell
endif

; CF: If block for personal slave follower mod. Might be useful to someone eventually.
if target.GetItemCount MS13Collar < 1 ; No collar means we missed its removal, somewhere... so remove all of this.
target.removeitem CFSlaveBook 1
target.removeitem CFpackageslavetoken 1
target.removeFromFaction MS13CollarFaction
target.RemoveFromFaction ParadiseFallsSlaveFaction
target.RemoveFromFaction FollowerFaction
endif

endif

end

 

 

Edited by CountFuzzball
Link to comment
Share on other sites

In other words, you are saving the modified value then restoring that value only to have it modified again and that puts the confidence value out of bounds.

 

Anyway, try using GetBaseAV and see if that fixes the issue.

Got some time to test this and you've just made my day! No more crashes and the respawned raiders behave as they should (trying to kick my ass!).

It really makes me scratch my head though why there would be a confidence modifier, when theoretically, the second if block in CFSlavePackageTravelScript should run exactly 1 frame after the mezzed effect goes away, and the real stats of the actor would then be read (again, there's the chance of a supremely bad race condition with the MS13CollarEffect, I would imagine, but I've never had that happen).

 

 

These three values are a bit different from other actor values. I don't know what happens if you try to set them to invalid numbers. I guess the base value would be the value programmed in the NPC record, but I've never used it. Just GetAV and SetAV for these.

Value ranges:

confidence 0-4

assistance 0-2

aggression 0-2

 

 

Thanks for those values. I had tried them before, using a bogstandard 'target.setav Confidence 4' and bam, it caused a crash. Very perplexing.

Link to comment
Share on other sites

Just a little *bump*. I did some testing with target.setav Confidence 3 using Raiders and I got no crashes, but when I do target.setav Confidence 4 (or even letting the target.getav confidence set to a variable and using that variable with target.setav), I do get a crash when the value is set (the raider's Confidence is set to 'Foolhardy' or '4' by default in the game's files). I am running a 'FOSE'ed fallout, admittedly. But I have no mods that would affect NPC stats.

Link to comment
Share on other sites

If you check in the game, using console commands, what is the Raider's confidence after you've set it to 3 using your script? Is it still 3, or is it something else?

 

Also, you can use the FOSE printc command along with the scof (Set Console Output File) command to dump output to a file you specify. This can be very useful for displaying variables in a text file for review prior to storing them in a variable that causes CTDs.

Link to comment
Share on other sites

Thanks for the reply, I used the scof, printtoconsole and printc to get the following output:

 

 

 

SetConsoleOutputFilename >> 'fosescriptoutputtest4.txt'

getav confidence

GetActorValue: Confidence >> 4.00

Starting collar script

Starting collar script

in the object script and assigned the confidence, we have set the starting confidence to

4.000000

In ScriptEffectUpdate. Put starting values into the local variables

Starting confidence is:

4.000000

In ScriptEffectUpdate. Put starting values into the local variables

Starting confidence is:

0.000000

setting confidence back to its original value of

Done

 

 

 

Oddly enough though, while getav confidence on the actor reports back 4 in the above example, it appears that sometimes the raider's confidence can be set to 3, for whatever reason. I even verified this on a minimally modded FO3 (only FO3 + DLCs + alternate start + the mod with these scripts).

N.B If the game crashes while setting getav startingconfidence (or '4') back onto the actor, then the 'done' message won't appear.

 

Example:

 

 

 

SetConsoleOutputFilename >> 'foseout.txt'

getav confidence

GetActorValue: Confidence >> 3.00

Starting collar script

Starting collar script

in the object script and assigned the confidence, we have set the starting confidence to

3.000000

In ScriptEffectUpdate. Put starting values into the local variables

Starting confidence is:

3.000000

In ScriptEffectUpdate. Put starting values into the local variables

Starting confidence is:

0.000000

setting confidence back to its original value of

 

 

 

Currently the scripts look like this:

 

 

scn MS13CollarEffectScript


;!!!!!!!!!!!!!!!!------------- the "don't dispel on death" flag in the Magic Effect form it needs to be marked so this script with work properly with the death on the actor ---------------!!!!!!!!!!!!!!!!!!!!!!!!

short arrived

short marked

short statsChanged ; set to 1 after Mezzed spell goes away and stats have been changed

; save original stats so we can restore them if collar removed
short StartingAggression
Short StartingAssistance
Short StartingConfidence
Short StartingEnergy
Short StartingResponsibility
Short StartingMood
short StartingIgnoreCrime

float alarmTimer

Begin ScriptEffectStart

set marked to 0
printtoconsole "Starting collar script"

PFallsAdultPenGate.unlock

; get rid of mezzed spell
dispel MS13MezzedSpell

;add to a faction which is friends with the player so that I won't aggro on player even if he has a crime tracking faction that hates the player
addToFaction MS13CollarFaction 0
set StartingIgnoreCrime to GetIgnoreCrime
ignoreCrime 1

; make sure running correct packages
if GetInCell PFallsSlaveHouse == 0 && getIsCurrentPackage MS13Enslaved == 0
AddScriptPackage MS13TravelToParadiseFalls
endif

if getitemcount CFpackageslavetoken < 1
additem CFpackageslavetoken 1
endif

End

Begin ScriptEffectUpdate
if statsChanged == 0
if HasMagicEffect MS13Mezzed == 0
; don't change stats until mezzed effect goes away, to make sure we're looking at REAL stats
set statsChanged to 1

; save stats for VIPs in case they're rescued after arriving in PF
if GetIsID Red == 1 && MS13.RedStatsChanged == 0
set MS13.RedStatsChanged to 1
set MS13.RedAggression to getAv aggression
set MS13.RedAssistance to getAv assistance
set MS13.RedConfidence to getAv confidence
elseif GetIsID Flak == 1 && MS13.FlakStatsChanged == 0
set MS13.FlakStatsChanged to 1
set MS13.FlakAggression to getAv aggression
set MS13.FlakAssistance to getAv assistance
set MS13.FlakConfidence to getAv confidence
elseif GetIsID SusanLancaster == 1 && MS13.SusanStatsChanged == 0
set MS13.SusanStatsChanged to 1
set MS13.SusanAggression to getAv aggression
set MS13.SusanAssistance to getAv assistance
set MS13.SusanConfidence to getAv confidence
elseif GetIsID Arkansas == 1 && MS13.ArkansasStatsChanged == 0
set MS13.ArkansasStatsChanged to 1
set MS13.ArkansasAggression to getAv aggression
set MS13.ArkansasAssistance to getAv assistance
set MS13.ArkansasConfidence to getAv confidence
endif

set StartingAggression to getAv Aggression
set StartingAssistance to getAv Assistance
set StartingConfidence to getAv Confidence
set StartingEnergy to getAv Energy
set StartingResponsibility to getAv Responsibility
set StartingMood to getAv Mood
printtoconsole "In ScriptEffectUpdate. Put starting values into the local variables"
printtoconsole "Starting confidence is:"
printc "%f" "StartingConfidence"

;set up AI data
if GetPlayerTeammate == 0
setAv Aggression 0
setAv Assistance 0
setAv Confidence 0
setAv Energy 5
setAv Responsibility 0
setAv Mood 4
endif

endif
endif

; send assault alarm after exiting dialogue
; use actor value so we make sure to only do this once
if getav variable09 == 0
if menumode == 0
set alarmTimer to alarmTimer + ScriptEffectElapsedSeconds
if alarmTimer > 2
setav variable09 9
SendAssaultAlarm
stopcombat
endif
endif
endif

; make sure running correct package
if GetItemCount MS13Collar < 1 ; No collar means we missed its removal, somewhere... so end the script
removeitem CFSlaveBook 1
removeitem CFpackageslavetoken 1
removeFromFaction MS13CollarFaction
RemoveFromFaction ParadiseFallsSlaveFaction
RemoveFromFaction FollowerFaction
if getIsCurrentPackage MS13TravelToParadiseFalls == 1
RemoveScriptPackage
endif
if getIsCurrentPackage MS13Enslaved == 1
RemoveScriptPackage
endif

ignoreCrime StartingIgnoreCrime

if GetIsID Red == 1 && MS13.RedStatsChanged == 1
set MS13.RedStatsChanged to 0
setav aggression MS13.RedAggression
setav assistance MS13.RedAssistance
setav confidence MS13.RedConfidence
elseif GetIsID Flak == 1 && MS13.FlakStatsChanged == 1
set MS13.FlakStatsChanged to 0
setav aggression MS13.FlakAggression
setav assistance MS13.FlakAssistance
setav confidence MS13.FlakConfidence
elseif GetIsID SusanLancaster == 1 && MS13.SusanStatsChanged == 1
set MS13.SusanStatsChanged to 0
setav aggression MS13.SusanAggression
setav assistance MS13.SusanAssistance
setav confidence MS13.SusanConfidence
elseif GetIsID Arkansas == 1 && MS13.ArkansasStatsChanged == 1
set MS13.ArkansasStatsChanged to 0
setav aggression MS13.ArkansasAggression
setav assistance MS13.ArkansasAssistance
setav confidence MS13.ArkansasConfidence
elseif statsChanged == 1
setAv Aggression StartingAggression
setAv Assistance StartingAssistance
setAv Confidence StartingConfidence
setAv Energy StartingEnergy
setAv Responsibility StartingResponsibility
setAv Mood StartingMood
endif
elseif GetPlayerTeammate == 1

elseif getIsCurrentPackage MS13TravelToParadiseFalls == 0 && getIsCurrentPackage MS13Enslaved == 0 && GetItemCount MS13Collar > 0
AddScriptPackage MS13TravelToParadiseFalls
endif

if arrived == 0
if getDead == 1 ; this only makes sense because the effect is marked not to be dispelled on death
if getitemcount CFSlaveIsDeadTOKEN == 0
additem CFSlaveIsDeadTOKEN 1
set arrived to -1
set MS13Slaves.slaveArrived to -1 ;(-1 = died)

GrouseRef.evp ;to get him walking to forcegreet the player
endif
elseif (getInCell ParadiseFallsExterior == 1 || GetInWorldspace ParadiseFalls == 1)
if getitemcount CFSlaveBook == 0
additem CFSlaveBook 1
;slave arrived on his own because he was a persistent actor, or a non-persistent actor who didn't unload (accompanied by the player)
set arrived to 1
if marked < 1
set MS13Slaves.numSlaves to MS13Slaves.numSlaves + 1
set marked to 1
endif

; add to slave faction so slavers react to player attacking
addToFaction ParadiseFallsSlaveFaction 0

;check to see if this is any of the named targets of MS13 and set the proper variable
if GetSelf == RedRef
if MS13.RedArrived == 0
set MS13.RedArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
elseif GetSelf == ArkansasRef
if MS13.ArkansasArrived == 0
set MS13.ArkansasArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
elseif GetSelf == FlakRef
if MS13.FlakArrived == 0
set MS13.FlakArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
elseif GetSelf == SusanLancasterRef
if MS13.SusanArrived == 0
set MS13.SusanArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
endif
else
; only for generic slaves
set MS13Slaves.slaveArrived to 1 ;(1 = he arrived for real)
set MS13Slaves.arriveDay to gamedayspassed

if getitemcount CFpackageslavetoken < 1
additem CFpackageslavetoken 1
endif
endif

GrouseRef.evp ;to get him walking to forcegreet the player

endif
endif
endif

; Only remove the slave once they've hung out in Paradise Falls for a day
; CF: Moved this into the CFSlaveTravelPackage script. Object scripts seem a better option for holding variable data stuff as they persist when
; the player leaves the object's cell and don't reset to 0 whenever the player re-enters the cell its in.

End


Begin ScriptEffectFinish
if MS13Slaves.debug == 1
ShowWarning "MS13CollarEffect -- ScriptEffectFinish"
endif

;This block will run if the spell is dispelled, which only happens when the NPC unloads (because the spell effect is marked not to dispell on death), of if the player removes the collar from the NPC
;--Except that's not true, because it can also happen during dialogs, or when you pause, or a thousand other things

if MS13Slaves.playerRemovedCollar == 1 || GetItemCount MS13Collar < 1
set MS13Slaves.playerRemovedCollar to -1

; reset stats back to original
removeFromFaction MS13CollarFaction
RemoveFromFaction ParadiseFallsSlaveFaction
RemoveFromFaction FollowerFaction
if getIsCurrentPackage MS13TravelToParadiseFalls == 1
RemoveScriptPackage
endif

set MS13Slaves.arriveDay to 0

ignoreCrime StartingIgnoreCrime

if GetIsID Red == 1 && MS13.RedStatsChanged == 1
set MS13.RedStatsChanged to 0
setav aggression MS13.RedAggression
setav assistance MS13.RedAssistance
setav confidence MS13.RedConfidence
elseif GetIsID Flak == 1 && MS13.FlakStatsChanged == 1
set MS13.FlakStatsChanged to 0
setav aggression MS13.FlakAggression
setav assistance MS13.FlakAssistance
setav confidence MS13.FlakConfidence
elseif GetIsID SusanLancaster == 1 && MS13.SusanStatsChanged == 1
set MS13.SusanStatsChanged to 0
setav aggression MS13.SusanAggression
setav assistance MS13.SusanAssistance
setav confidence MS13.SusanConfidence
elseif GetIsID Arkansas == 1 && MS13.ArkansasStatsChanged == 1
set MS13.ArkansasStatsChanged to 0
setav aggression MS13.ArkansasAggression
setav assistance MS13.ArkansasAssistance
setav confidence MS13.ArkansasConfidence
elseif statsChanged == 1
setAv Aggression StartingAggression
setAv Assistance StartingAssistance
setAv Confidence StartingConfidence
setAv Energy StartingEnergy
setAv Responsibility StartingResponsibility
setAv Mood StartingMood

printtoconsole "in scripteffectfinish block. We have set the confidence back to StartingConfidence which is:"
printc "%f" StartingConfidence
endif
elseif GetInSameCell player != 1
;assume the NPC unloaded -- which we can only assume if they aren't in the same cell

;if the slave hasn't arrived yet, we'll fake it as if he did arrive when the player wasn't looking (he's not in the same cell as the player or he wouldn't have unloaded)
if arrived == 0
if getitemcount CFSlaveBook == 0
additem CFSlaveBook 1
set MS13Slaves.arriveDay to gamedayspassed
set arrived to 2
if marked < 1
set MS13Slaves.numSlaves to MS13Slaves.numSlaves + 1
set marked to 1
endif
set MS13Slaves.slaveArrived to 2 ;(2 = we faked his arrival)
; add to slave faction so slavers react to player attacking
addToFaction ParadiseFallsSlaveFaction 0

if GetSelf == RedRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.RedArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
elseif GetSelf == ArkansasRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.ArkansasArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
elseif GetSelf == FlakRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.FlakArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
elseif GetSelf == SusanLancasterRef
moveto ParadiseFallsSlaveHouseMARKER
set MS13.SusanArrived to 1
set MS13Slaves.slaveArrived to 0 ;or you'll get generic dialog instead of dialog refering to the target slave
setstage MS13 100
GrouseRef.evp ;to get him walking to forcegreet the player
else
;it was someone else
set MS13Slaves.arriveDay to GameDaysPassed
GrouseRef.evp

if getitemcount CFpackageslavetoken < 1 ; CF: Probably should move this into the oneffectstart block
additem CFpackageslavetoken 1 ; CF: this can run "too fast".
endif
;moveto ParadiseFallsSlaveHouseMARKER
endif

;GrouseRef.evp ;to get him walking to forcegreet the player

endif
endif

endif

endif

End

 

 

 

 

 

 

 

 

 

scn CFSlavePackageTravelScript
ref target
short statsChanged
short StartingAggression
Short StartingAssistance
Short StartingConfidence
Short StartingEnergy
Short StartingResponsibility
Short StartingMood
short StartingIgnoreCrime

begin gamemode

set target to getContainer

if target == 0
Return ; getContainer doesn't always work first time around.
else

if statsChanged == 0
if target.HasMagicEffect MS13Mezzed == 0
; don't change stats until mezzed effect goes away, to make sure we're looking at REAL stats
set statsChanged to 1

set StartingAggression to target.getAv Aggression
set StartingAssistance to target.getAv Assistance
set StartingConfidence to target.getAv Confidence
set StartingEnergy to target.getAv Energy
set StartingResponsibility to target.getAv Responsibility
set StartingMood to target.getAv Mood
set StartingIgnoreCrime to target.getignorecrime
printtoconsole "in the object script and assigned the confidence, we have set the starting confidence to"
printc "%f" StartingConfidence
endif
endif


if ((target.getDistance player > 100 && target.getInSameCell Player == 0) || target.getInSameCell Player == 0) && target.getincell pfallsslavehouse == 0 && target.GetItemCount MS13Collar > 0

; This is handled by the collar script if the collar is removed.
;target.RemoveFromFaction MS13CollarFaction
;target.RemoveFromFaction ParadiseFallsSlaveFaction
;target.RemoveFromFaction FollowerFaction

if target.getInFaction WastelanderFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
target.moveto CFWastelanderMarkerREF ;-- Just stash the body somewhere if/until they respawn
elseif target.getInFaction RCSecurityFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
target.moveto CFRCSecurityMarkerREF ;-- Just stash the body until they respawn
elseif target.getInFaction RaiderFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance

printtoconsole "setting confidence back to its original value of"
printc "%f" StartingConfidence

target.setAv Confidence 4
printtoconsole "Done"
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
;target.moveto player ;
target.moveto CFRaiderMarkerREF
elseif target.getInFaction EnclaveFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
target.moveto CFEnclaveMarkerREF ;-- Just stash the body somewhere until they respawn
elseif target.getInFaction BrotherHoodOutCastFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
target.moveto CFWastelanderMarkerREF ;-- Just stash the body somewhere until they respawn
elseif target.getInFaction TalonCompany == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
target.moveto CFTalonMarkerREF ;-- Just stash the body somewhere until they respawn
elseif target.getInFaction BrotherHoodSteelFaction ==1 ; Or BrotherHoodSteelGenericFaction?
target.moveto CFWastelanderMarkerREF ;-- Just stash the body somewhere until they respawn
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
elseif target.getInFaction RegulatorFaction == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.setAv Aggression StartingAggression
target.setAv Assistance StartingAssistance
target.setAv Confidence StartingConfidence
target.setAv Energy StartingEnergy
target.setAv Responsibility StartingResponsibility
target.setAv Mood StartingMood
target.ignorecrime StartingIgnoreCrime
target.KILL
target.moveto CFRegulatorMarkerREF ;-- Just stash the body somewhere until they respawn
else ; generic npc
target.moveto ParadiseFallsSlaveHouseMARKER
target.AddScriptPackage MS13Enslaved
endif
endif

; Only remove the slave once they've hung out in Paradise Falls for a day
; Need this block here so it always runs. After acquring numerous slaves, the scripteffectupdate block only runs on the last slave captured.
if MS13Slaves.arriveDay != 0 && ( GameDaysPassed - MS13Slaves.arriveDay > 1 ) && target.getincell pfallsslavehouse == 1
target.RemoveItem MS13Collar 1
target.RemoveItem CFSlaveBook 1
target.RemoveItem CFpackageslavetoken 1
target.KILL
target.moveto FFEnclaveEncampmentMasterREF
endif

; CF: If block for personal slave follower mod. Might be useful to someone eventually.
;if target.GetItemCount MS13Collar < 1 ; No collar means we missed its removal, somewhere... so remove all of this.
; target.removeitem CFSlaveBook 1
; target.removeitem CFpackageslavetoken 1
; target.removeFromFaction MS13CollarFaction
; target.RemoveFromFaction ParadiseFallsSlaveFaction
; target.RemoveFromFaction FollowerFaction
;endif

endif

end

 

 

 

The strange thing is, I *appear* to be getting less crashes with this.. it's like a 1 in 10 chance of crashing or so,it appears. I now have no reliable way to reproduce it. I will need to do a bit more testing to see.

Edited by CountFuzzball
Link to comment
Share on other sites

You could try to see if it's a persistence issue. Test only on NPCs that are persistent in the editor as opposed to spawned actors.

Also - there's no need to SetAV their starting stats if you're just going to kill them with the last command.. I think the vanilla script does it because - I think there is a small window to release them?

Link to comment
Share on other sites

I'll see if persistant actors react any differently, differently, as this has ramifications for if/when a collar is removed on an enslaved actor and stats are required to be set back to their original values (admittedly, this would be counter to what has already been said about being able to use object scripts to assign those values for companions etc).

 

In truth, I've come to the conclusion that doing a 'setav' on the actors if they respawn is an incredibly misguided move on my part, once I realised what the problem was with 'friendly raiders'.

I assumed they were friendly because their stats were still the same, so they didn't attack.

 

In other words, I assumed that the code commented in MS13SlaveCollarEffect 'missed collar removal, end the script' (supposed to remove them from the PFSlavefaction and the player-friendly follower faction) with a condition of 'if getitemcount ms13slavecollar == 0' in the 'scripteffectupdate' block *actually freaking ran*. Of course in true Bethesda Softworks style, this wasn't the case. I've since included that block in the 'cleanup' part of my object script. I wait 3 three ingame days and voila, 3 very ill-tempered and heavily armed raiders waiting for me in Springvale school.

 

 

Having said the above.. and after having commented out the 'setav xyz to startingxyz' lines', I still got a crash just as the raider is 100 ingame units from me and left the cell (i.e he's in an exterior cell/worldspace). This is plain frustrating. The actor persistance issue might sound about right, I'll test that next. Maybe the object is losing its reference to the actor or something when its not in an interior cell, so the 'target' ref is set to 0, therefore it crashes. Or it could very well be the collar script having a hiccup or somesuch.

 

EDIT: Also, I quickly coded up a baseball bat that has a scripted affect to attach an object to hit actors so it changes their confidence, etc. I smacked a few raiders with it and no crashes. Guess that throws out the 'target.setav confidence 4' crashes stuff. Gotta dig deeper it seems.

Edited by CountFuzzball
Link to comment
Share on other sites

  • Recently Browsing   0 members

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