Gribbleshnibit8 Posted July 19, 2012 Share Posted July 19, 2012 So, in making the Alt Start series of mod something that was truly worth using over and over, I wrote a series of relatively (for me anyway) complex scripts to handle dynamically chosen and randomized selections of weapons and starting equipment for players. I spent quite a lot of time getting the things to work correctly, helped along by people from the community (I forget now who all I had help from, as I wrote these almost 2 years ago). In the update for Fallout: New Vegas, I nearly rewrote the entire mod (from the Fallout 3 version) to be more efficient and to add new features. Since I'm done with the mod, and I learned quite a bit from this work, I figured I'd share what I've learned with others, in the hopes that this information might help someone else with a project of theirs. So here's just the initial weapon adding script, which adds a primary weapon based on the player's guns skill, and an option choice of which type of weapon they prefer.if (AltStart.SkillGuns > 0) && (AltStart.weapChoice == 0) ;handles any choice; DEFAULT set rWeapList to StartWeapGuns elseif (AltStart.SkillGuns > 0) && (AltStart.weapChoice == 1) ;handles pistol choice set rWeapList to StartWeapPistol elseif (AltStart.SkillGuns > 0) && (AltStart.weapChoice == 2) ;handles rifle choice set rWeapList to StartWeapRifle elseif (AltStart.SkillGuns > 0) && (AltStart.weapChoice == 3) ;handles shotgun choice set rWeapList to StartWeapShotgun endif if (AltStart.SkillGuns > 0) ; printc "adding gun" ;set variables for use in this block (reused in each block) set healthBonus to (GetRandomPercent * (AltStart.bonAmount) / 99) set healthPenalty to (GetRandomPercent * (AltStart.penAmount) / 99) set sItemHealth to ((Player.GetAV Repair - healthPenalty + healthBonus) / 100) set sItemIndex to (AltStart.SkillGuns + AltStart.HistBg) - 1 set rListName to ListGetNthForm rWeapList sItemIndex ;get the list with weapons at the level to be added (poor, moderate, decent, good) set sListLength to ListGetCount rListName ;get the length of the retrieved list set randVal to ((GetRandomPercent * sListLength) / 99) ;get a random value for retrieval of a weapon from the weapons list set rItemBase to ListGetNthForm rListName randVal ;get the weapon to be added from the list using the calculated random value Player.AddItemHealthPercent rItemBase 1 sItemHealth 1 set rAmmoType to GetWeaponAmmo rItemBase ;get ammo type and clip size for the added weapon set sClipSize to GetWeaponClipRounds rItemBase ;determine how much ammo should be added for the weapon if (sItemIndex == 0) set sNumClips to 1 else set sNumClips to sItemIndex endif set randVal to ((GetRandomPercent * sClipSize) / 99) if (sClipSize > 12) set sAddAmmo to ((sClipSize * sNumClips) + randVal) elseif (sClipSize > 2) set sAddAmmo to (((sClipSize * sNumClips) + randVal) * AltStart.GunsAmmoMult1) else set sAddAmmo to (((sClipSize * sNumClips) + randVal) * AltStart.GunsAmmoMult2) endif ;if Player has scrounger perk (added by certain histories), add more ammo to them if (Player.HasPerk Scrounger) set sAddAmmo to sAddAmmo + ( 2 * ((GetRandomPercent * sClipSize) / 99)) endif ;find out what type of ammo the gun uses (list or ammo) if (GetType rAmmoType == 41) ;is an ammo type, can continue as normal set sAddAmmo to (sAddAmmo * AltStart.sDifficultyMult) Player.AddItem rAmmoType sAddAmmo 1 elseif (GetType rAmmoType == 85) ;is a list of ammo, must do additional work set rAmmoList to rAmmoType set sListLength to ListGetCount rAmmoList set sCountLength to 0 Label 10 set rAmmoType to ListGetNthForm rAmmoList sCountLength if (sCountLength == 0) ;for first ammo in list, handle as normal set sAddAmmo to (sAddAmmo * AltStart.sDifficultyMult) Player.AddItem rAmmoType sAddAmmo 1 else ;for all the rest of the ammos set randVal to GetRandomPercent ;get a random value if (randVal < AltStart.specialAmmoChance) ;chance of getting special ammo set sAddAmmo to ((sClipSize + randVal)/10) * (AltStart.LuckBonus/4) ;Reduces amount of special ammo Player.AddItem rAmmoType sAddAmmo 1 endif endif set sCountLength to (1 + sCountLength) if (sCountLength < sListLength) Goto 10 endif endif ;determine if the Player should get a weapon mod for this weapon set sCountLength to 1 set sModChance to AltStart.sWeapModChance Label 20 set rWeapMod to GetWeaponItemMod sCountLength rItemBase if (rWeapMod) set randValTwo to GetRandomPercent if (randValTwo <= sModChance) Player.AddItem rWeapMod 1 1 set sModChance to sModChance + 6 endif endif set sCountLength to (1 + sCountLength) if (sCountLength < 4) Goto 20 endif set hasGun to 1 endif It obviously does more than just that, so I'll try to just walk through what each section does. set healthBonus to (GetRandomPercent * (AltStart.bonAmount) / 99) set healthPenalty to (GetRandomPercent * (AltStart.penAmount) / 99) set sItemHealth to ((Player.GetAV Repair - healthPenalty + healthBonus) / 100) set sItemIndex to (AltStart.SkillGuns + AltStart.HistBg) - 1 set rListName to ListGetNthForm rWeapList sItemIndex ;get the list with weapons at the level to be added (poor, moderate, decent, good) set sListLength to ListGetCount rListName ;get the length of the retrieved list set randVal to ((GetRandomPercent * sListLength) / 99) ;get a random value for retrieval of a weapon from the weapons list set rItemBase to ListGetNthForm rListName randVal ;get the weapon to be added from the list using the calculated random value Player.AddItemHealthPercent rItemBase 1 sItemHealth 1 set rAmmoType to GetWeaponAmmo rItemBase ;get ammo type and clip size for the added weapon set sClipSize to GetWeaponClipRounds rItemBaseThis section starts off by determining random values by which to calculate the item's health. The AltStart.bonAmount and AltStart.penAmount are quest variables that are set by the player's choice of what history they use. This lineset sItemIndex to (AltStart.SkillGuns + AltStart.HistBg) - 1uses the player's history choice to determine what level of guns the player can get. Guns have been divided into four groups based on how good the gun is. The next section is commented, so I will just describe what it does. Once the script has the list with the weapons in it, it finds the length of that list, and then generates a random value between 0 (first index of the list) and the last index of the list. That way the number will fall within the range of the number of items on the list, ensuring that we always give an item. Once it has a number it sets the item in that index to a variable, from which we can use it as though we were referring to the form name of that item. Then it just gets added to the player with the previously calculated health value. The last two lines of that section get the ammo type the weapon uses and the number of rounds the weapon holds in each clip for use in later sections. ;determine how much ammo should be added for the weapon if (sItemIndex == 0) set sNumClips to 1 else set sNumClips to sItemIndex endif set randVal to ((GetRandomPercent * sClipSize) / 99) if (sClipSize > 12) set sAddAmmo to ((sClipSize * sNumClips) + randVal) elseif (sClipSize > 2) set sAddAmmo to (((sClipSize * sNumClips) + randVal) * AltStart.GunsAmmoMult1) else set sAddAmmo to (((sClipSize * sNumClips) + randVal) * AltStart.GunsAmmoMult2) endif ;if Player has scrounger perk (added by certain histories), add more ammo to them if (Player.HasPerk Scrounger) set sAddAmmo to sAddAmmo + ( 2 * ((GetRandomPercent * sClipSize) / 99)) endifThe first check for sItemIndex == 0 just lets us know if the weapon is for the lowest tier weapons, in which case you only get a clip of ammo for it, otherwise the number of clips is based on the item index number (duh, huh?). Then we get a random number less than or equal to a full clip of ammo for this weapon. Next we check for clip sizes, adding ammo based on the clip size, with lower clip size weapons getting a higher proportional number of rounds per clip size. This is just to ensure that a player with a single shotgun gets enough rounds to actually survive at least their first encounter with enemies (hopefully). The GunsAmmoMult* values are set in an initialization script along with all other quest variables. A final check for the Scrounger perk adds some extra ammo. This next section was added new to the Fallout: New Vegas version, due to the fact that it uses ammo lists instead of ammo forms. It does however account for weapons that do use a single ammo form, such as the Fat Man or any mod added weapons.;find out what type of ammo the gun uses (list or ammo) if (GetType rAmmoType == 41) ;is an ammo type, can continue as normal set sAddAmmo to (sAddAmmo * AltStart.sDifficultyMult) Player.AddItem rAmmoType sAddAmmo 1 elseif (GetType rAmmoType == 85) ;is a list of ammo, must do additional work set rAmmoList to rAmmoType set sListLength to ListGetCount rAmmoList set sCountLength to 0 Label 10 set rAmmoType to ListGetNthForm rAmmoList sCountLength if (sCountLength == 0) ;for first ammo in list, handle as normal set sAddAmmo to (sAddAmmo * AltStart.sDifficultyMult) Player.AddItem rAmmoType sAddAmmo 1 else ;for all the rest of the ammos set randVal to GetRandomPercent ;get a random value if (randVal < AltStart.specialAmmoChance) ;chance of getting special ammo set sAddAmmo to ((sClipSize + randVal)/10) * (AltStart.LuckBonus/4) ;Reduces amount of special ammo Player.AddItem rAmmoType sAddAmmo 1 endif endif set sCountLength to (1 + sCountLength) if (sCountLength < sListLength) Goto 10 endif endifSo the first check is for an ammo form type, in which case we just add the calculated number of rounds and we're done. For an ammo list, it gets more complicated, because it needs to have a chance to add some of each type of ammo on the list. This again accounts for all mod added ammo types, and will iterate through the list until the end. As you can see though, the first ammo type in the list is assumed to be the default ammo type, or normal ammo for that weapon, and gets added like it would without a list present. The sDifficultyMult variable is an unimplemented difficulty mod designed to allow players to change how hard they want their game to be at the start. specialAmmoChance is set to a 33 percent chance (for each iteration through) of getting a special ammo type. Then it finds a random amount, with a relation to Luck playing into how much you get. This last section is newest, and undocumented. I referenced Pelinor's The Weapon Mod Menu for how to access the weapon mod data for weapons. There is an almost complete lack of documentation on these NVSE functions, which makes them rather difficult to use.set sCountLength to 1 set sModChance to AltStart.sWeapModChance Label 20 set rWeapMod to GetWeaponItemMod sCountLength rItemBase if (rWeapMod) set randValTwo to GetRandomPercent if (randValTwo <= sModChance) Player.AddItem rWeapMod 1 1 set sModChance to sModChance + 6 endif endif set sCountLength to (1 + sCountLength) if (sCountLength < 4) Goto 20 endifWe first set our count variable to 1, then get the chance for mods, another one of those unimplemented variables that could allow players the ability to select the chance for getting weapon mods. The GetWeaponItemMod function returns the first mod item used by that weapon. More accurately, the function returns the item at the index number provided in the formset rItem to GetWeaponItemMod int:int item:refSince I'm using a variable at the int, I can increment it by one through a loop and move through each weapon mod slot on the weapon. It also performs a check to ensure that the weapon mod returned is a valid item, to make sure we don't add a null item, which would probably crash the game. As I'm writing this I see a mistake in here, the lineset sModChance to sModChance + 6should actually be set sModChance to sModChance [b]-[/b] 6, in order to make the chance for getting a subsequent mod smaller, not greater. That's a whoops on my part. Well that's how it works. This is the most complex part of the mod. The armor adding script is similar, without all the weapon specific stuff. Armors just get health values, and are equipped after being added. Not even sure if anyone cares about this or will use it, but I figured I had it, I'd put it out here for anyone to look at. If you have questions, just ask. If you'd like to see the full code, you can go check out the mod here and look at the code in context. Link to comment Share on other sites More sharing options...
Recommended Posts