PAPVAFS11 Posted August 8, 2016 Share Posted August 8, 2016 My goal with this script is to allow a one-size-fits-all leveled list to work for both Capital Wasteland and Mojave Wasteland NPCs in Tale of Two Wastelands without either using incorrect weapons for the locale. Here's the script I'm using: scn CYCWCChineseAssaultRifleWasterSCRIPT ref rHolder begin GameMode if (rHolder != GetContainer) ; Set the reference so we can add the item. set rHolder to GetContainer else if (rHolder != 0) ; Ensure the item is in a container before proceeding. if (bInDCWasteland == 1) || (GetRandomPercent == 1) rHolder.AddItem WithAmmoChineseAssaultRifleNPC 1 1 else rHolder.AddItem WithAmmoAssaultRifleNPC 1 1 endif endif RemoveMe ; Remove the misc item as it's done its job. endif EndThis runs on a misc item that, as the code might suggest, is intended to transform into the appropriate weapon. When added to the player or an NPC via the AddItem command, this works just fine and it functions correctly. I've ensured that leveled lists inside the script exist and I know that the global exists, so I don't think they're the problems. On NPCs that are just spawning into the world, however (in my case, a test NPC spawned with the PlaceAtMe command), the game locks up and has to be ended with the task manager. I've tried adding a timer to the script to give the NPC time to load in, but that only delayed the crash until after the timer expired. This script has to function with an item that has to be part of a leveled list. If it can't, it's entirely useless and I'll be forced to juggle even more leveled lists for the Mojave (which is a problem as I've got way too many for just D.C.). What am I doing wrong and how can I fix it? Link to comment Share on other sites More sharing options...
uhmattbravo Posted August 8, 2016 Share Posted August 8, 2016 (edited) I can't guarantee it'll work any better, but have you tried it using getself instead of getcontainer for the container ref and/ or rholder.removeitem (scripted object's baseid) 1 instead of removeme? If nothing else it's worth trying because some functions can get a little picky with how they work in certain situations. Edited August 8, 2016 by uhmattbravo Link to comment Share on other sites More sharing options...
PAPVAFS11 Posted August 9, 2016 Author Share Posted August 9, 2016 Unfortunately, that didn't work. While it didn't crash, the script failed to do anything with GetSelf in place of GetContainer. Still, it was worth a shot and I appreciate the suggestion. Is there anyone out there who might've run into the same problem? Link to comment Share on other sites More sharing options...
PAPVAFS11 Posted August 9, 2016 Author Share Posted August 9, 2016 I may have spoken too soon. I narrowed down the crash to the RemoveMe call and did some juggling with it. While RemoveMe crashed no matter what I did, using rHolder.RemoveItem in a very particular way worked perfectly. What I did was add in a boolean check in a particular way to ensure that the GameMode block runs to completion at least once before the item is removed. This gives the item time to "settle" before it's removed and seems to be preventing the crash. Here's the code I'm using now: scn CYCWCChineseAssaultRifleWasterSCRIPT ; Converts weapons dependent on the wasteland it's in. ref rHolder int bGiven begin GameMode if (bGiven == 1) rHolder.RemoveItem CYCWCChineseAssaultRifleWaster 1 1 endif if (rHolder != GetContainer) set rHolder to GetContainer else if (rHolder != 0) && (bGiven == 0) if (bInDCWasteland == 1) || (GetRandomPercent == 1) rHolder.AddItem WithAmmoChineseAssaultRifleNPC 1 1 else rHolder.AddItem WithAmmoAssaultRifleNPC 1 1 endif set bGiven to 1 endif endif EndI don't think this is quite perfect as it could result in a situation where multiples of this item could only convert to one weapon (or so my often-fallible logic leads me to believe). Regardless, it's working now, so I'm going to run with it. If anything else comes up, I'll report again. Link to comment Share on other sites More sharing options...
rickerhk Posted August 9, 2016 Share Posted August 9, 2016 Yes, it's important to give the game world a chance to catch up and not try to do everything in one frame. I think Getself returns zero on placeAtMe actors, so Getcontainer is what to use. I have always had to skip a frame before doing any equipment stuff to the actor. The removeMe in the same frame as adding the misc item is also a CTD magnet :smile:I don't know if it still applies, but at one time there was a game bug where the script could loop again after removeMe, and therefore run the command again, causing a CTD. So I always guard that function so there's no way it could run again. scn CYCWCChineseAssaultRifleWasterSCRIPT ref rHolder short iStage begin GameMode if (rHolder) ; Set the reference so we can add the item. (skip if already set) else set rHolder to GetContainer set iStage to 1 endif if (rHolder) ; Ensure the item is in a container before proceeding. if (iStage == 1) set iStage to 2 ;Do nothing. Just skip a frame elseif (iStage == 2) if (bInDCWasteland == 1) || (GetRandomPercent == 1) rHolder.AddItem WithAmmoChineseAssaultRifleNPC 1 1 else rHolder.AddItem WithAmmoAssaultRifleNPC 1 1 endif set iStage to 3 ;skip another frame elseif (iStage == 3) set iStage to 4 ;make sure there's no chance removeme will run twice RemoveMe ; Remove the misc item as it's done its job. endif endif End Link to comment Share on other sites More sharing options...
RoyBatterian Posted August 10, 2016 Share Posted August 10, 2016 Thanks for that tip on removeme rickerhk! Link to comment Share on other sites More sharing options...
Recommended Posts