Jump to content

Can someone give me feedback on this script?


johnbturnip

Recommended Posts

I'm working on a mod similar to Deviously Cursed Loot, except it will allow other modders to add any item they want to it, rather than hardcoding every item into the script.  So far, it works exactly as intended.  However, I just want to make sure that I didn't fall into any common Papyrus Pitfalls with my prototype.

Did I make any obvious no-no's so far?  Will this cause save bloat, heavy script lag, or incompatibility?  (Well, incompatibility shouldn't be an issue)

 

Scriptname JBT_SurpriseEquipQuestScript extends Quest  

	;CURRENT MOD REQUIREMENTS:
	;*SKSE
	;*PapyrusUtil
	
	
	;Properties/variables
	
	Form Property SteelSword auto 
	
	FormList Property JBT_SurpriseItemList auto
	Float Property totalWeight = 0.0 auto
	Float Property surpriseChance = 0.1 auto		;Probability that a given container will be trapped.
	
	ObjectReference openContainer = None
	
	;PapyrusUtil key names
	String Property itemWeight = "JBT_surpriseItemWeight" autoreadonly
	String Property alreadyLooted = "JBT_alreadyLootedContainerWeight" autoreadonly
	
	;Events
	
	Event OnInit()
	
		Debug.Notification("JBT Surprise initialized")
		
		;Register for container close event
		RegisterForMenu("ContainerMenu")
		
		;TEST: Register an item
		RegisterItem(SteelSword, 1)
		
	EndEvent
	
	Event OnMenuOpen(String menuName)
	
		if (menuName == "ContainerMenu")
			;Get the opened container
			openContainer = Game.GetCurrentCrosshairRef()
		endif
	
	EndEvent
	
	Event OnMenuClose(String menuName)
		;Clear the current open container, but keep a copy of it for this function
		ObjectReference containerOpened = openContainer
		openContainer = None
		
		;Don't go on if this wasn't a container.
		if (menuName != "ContainerMenu")
			return
		endif
		
		;Don't go on if we've already looted this container
		if (StorageUtil.GetIntValue(containerOpened, alreadyLooted, 0))
			Debug.Notification("Already looted container " + containerOpened.GetName())
			return
		endif
		
		;Mark this container as having already been opened
		StorageUtil.SetIntValue(containerOpened, alreadyLooted, 1)
		
		;Only go on if we pass the dice roll
		Float dice = Utility.RandomFloat(0.0, 1.0)
		if (dice > surpriseChance)
			Debug.Notification("No random surprise this time.")
			return
		endif
		
		Debug.Notification("Dice roll passed.  Equipping surprise item!")
		
		;Equip a random item
		EquipRandomItem(Game.GetPlayer())
		
	EndEvent
	
	
	;Functions
	
	Function RegisterItem(Form akItem, Float weight)
		;Registers the given item to the random list.
		
		;Don't go on if already registered.
		if (JBT_SurpriseItemList.HasForm(akItem))
			return
		endif
		
		;Add it to the list
		JBT_SurpriseItemList.AddForm(akItem)
		StorageUtil.SetFloatValue(akItem, itemWeight, weight)
		totalWeight += weight
		
		Debug.Notification("Registered item " + akItem.GetFormID())
		
	EndFunction
	
	Function ChangeItemWeight(Form akItem, Float weight)
		;Changes the weight of an already-registered item
		
		;Don't go on if the item isn't registered.
		if (!JBT_SurpriseItemList.HasForm(akItem))
			return
		endif
		
		;Update the total weight
		totalWeight += weight - StorageUtil.GetFloatValue(akItem, itemWeight)
		
		;Change the item's weight
		StorageUtil.SetFloatValue(akItem, itemWeight, weight)
	EndFunction
	
	Function EquipRandomItem(Actor akVictim)
		;Equips a random item from the list to the victim.
		
		;TODO: Take item weights into account
		
		;Draw a random item from the pool
		Form item = GetRandomItem()
		Debug.Notification("Selected item " + item.GetFormID())
		akVictim.EquipItem(item, false, false)
		
	EndFunction
	
	Form Function GetRandomItem()
		;Returns a random item, taking weights into account.
	
		;Generate a random value between 0 and the total weight
		Float val = Utility.RandomFloat(0, totalWeight)
		
		;See which item it corresponds to
		int i = 0
		Float runningWeight = 0
		While (i < JBT_SurpriseItemList.GetSize())
		
			;Get the Form
			Form item = JBT_SurpriseItemList.GetAt(i)
		
			;Update the running weight
			runningWeight += StorageUtil.GetFloatValue(item, itemWeight)
			
			;Return this item if val is less than the running weight
			if (val <= runningWeight)
				return item
			endif
			
			;Move on.
			i += 1
		EndWhile
		
		;If we get this far, it's an error.
		return None
	EndFunction

Other mods will call the RegisterItem() function to add their item to the list.  The ESP file adds both the appropriate quest and the FormList that the items get added to.

Thanks in advance for the feedback!

Link to comment

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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