Jump to content

Quick Questions, Quick Answers


Mattiewagg

Recommended Posts

Thanks for the quick answer Ishara, I test it right now.

 

Thanks again Kudo for the help :thumbsup:

 

OK I understand better, find it on CK wiki according to your response:

 

  • "Single equals sign (=) means: Take the what's on the right and shove it into the variable on the left.
  • Double equals sign (==) means: Is the thing on the left the same as the thing on the right"

 

Edit: this work as expected, perfect :thumbsup:

Edited by dredd3110
Link to comment
Share on other sites

  • 2 weeks later...
  • Replies 2.6k
  • Created
  • Last Reply

Top Posters In This Topic

Hey everyone!

 

I'm looking into ways to link chests together, but the catch is that one part of the link is dynamically generated. I was wondering if anyone has any experience with this sort of thing, or any idea how I might achieve such a link.

 

Thanks, and take care!

How do you mean link? Like a linked reference? I don't believe that you can dynamically achieve those, but you could easily fill up a variable or property dynamically. If you're not familiar with those, let me know, and I can provide you with some links. A property or variable is easily filled with something else, but I'm not sure what kind of dynamic filling do you want. Do you provide the chest that you're going to link to the script, or are you trying to dynamically find it within the script itself, and if so - what are your parameters?

Link to comment
Share on other sites

Hey everyone!

 

I'm looking into ways to link chests together, but the catch is that one part of the link is dynamically generated. I was wondering if anyone has any experience with this sort of thing, or any idea how I might achieve such a link.

 

Thanks, and take care!

 

Do you mean like a Ender Chest from Minecraft?

A chest that shares storage space with all other similar chests?

Link to comment
Share on other sites

I've modified an existing script that someone made for me a while ago. When you click on an activator, 4 firewood is removed from your inventory and a fire is enabled. It will disable itself after 8 hours. Here it is...

 

 

 

Scriptname SCFireLight extends ObjectReference

ObjectReference Property FireXMarker Auto
MiscObject Property Firewood01 Auto
Float fTimeIgnited
Float fCurrentTime

Event OnActivate(ObjectReference akActionRef)
If (Game.GetPlayer().GetItemCount(Firewood01) >= 4)
Game.GetPlayer().RemoveItem(Firewood01, 4)
FireXMarker.enable()
fCurrentTime = Utility.GetCurrentGameTime()
fTimeIgnited = fCurrentTime
Else
Debug.Notification("You Need 4 Pieces Of Firewood")
EndIf
EndEvent

Event OnCellAttach()
fCurrentTime = Utility.GetCurrentGameTime()
If fCurrentTime > (fTimeIgnited + 0.33)
FireXMarker.disable()
EndIf
EndEvent

 

 

 

I have tested it and everything seems to be working. Questions...

 

1) Are there any potential problems with the script?

2) Is there any way I can make the script update periodically? At the moment it only updates when the cell is entered.

3) Is there a way of updating it when a player sleeps in the same cell?

Edited by Thicketford
Link to comment
Share on other sites

Hey, thanks so much everyone for your responses!

Mattiewagg, you can fill properties dynamically, like in script as opposed to statically in the Creation Kit? I never knew that, and could be quite useful. You're talking about properties such as "ObjectReference Property test Auto?"
I'll attempt to be more clear in what I'm attempting: say I have five chests in a storage cell that never change. Then there are five chests spawned in the world whenever the player feels they need five chests (not actually what my mod does, just an example.) To avoid item loss, I want to basically say something like chest01 in the world belongs to chest01 in the storage cell at all times. So when you access chest01 in the world, your inventory goes to that same chest, but in the storage cell. I do hope that makes sense. =-)

Necrocytosis, mm, something like that, yes. But where each Ender Chest only goes to another specific Ender Chest, and not accessible to all Ender Chests (if I remember how those work in Minecraft.) Kind of like that mod for Minecraft where you basically color-code Ender Chests to make them go to a specific chest with the same color. The name escapes me right now, though.


As a bit of an update, I found a solution using a combination of PapyrusUtil (which may be unnecessary as I only use it to make globally available lists) and SKSE, but am still interested in other ways to achieve the same thing.
I'll do my best to explain everything, but if I'm not clear, do let me know! There is no short version, so please bare with me.

My mod basically allows a player home to be spawned anywhere in the world, and as part of this, I do a lot of complex calculations. To simplify the placing of the home, I used JContainers to write every possible static calculation result, as well as every object's base form, to an external file. This information is then read from the file and placement of the home begins. I then use Game.GetFormFromFile to basically compare each item as they're placed to an activator that I've made that looks like a chest (GetFormFromFile is the only way I found to make the activator's ID be mod index-independent.) If one is found, it's stored in a PapyrusUtil formlist, which admittedly is probably silly as you could probably use a built-in array. I'll refine it later, I suppose.
Anyways, as each item is stored, I alter its base form name to be something like chest, chest0, chest1, etc. and set its display name to be simply "chest" as otherwise I end up with a chest named something like "chest32."
This next part is where SKSE's StringUtil functions come into play. In a separate script that is attached to each chest, I do a generic OnActivate() event. In this event, I basically take in the base form name of the activated object, say chest25, peel off the chest part, turn the 25 part into an int, and use that in an ObjectReference property array that contains all chests in a storage cell, ending with a check to see if the activator was accessed by the player and finally telling storageCellChest[25] to activate, showing its inventory in place of the chest that player actually sees.

It's complicated, maybe a bit convoluted, but it does work, and works reliably.
The only caveat is that you have to reset the base form's name each time the game is reloaded, as well as the display name, otherwise, well, none of the string manipulation will work and it would just be a mess.

In the highly likely chance none of that made sense, here's some code. =-)
The first is a non-functional read script snippet

Form chestRep = Game.GetFormFromFile(0x0000000F, "YourMod.esp") as Form

int i = 0
int c = 0

while i < JArray.count(object)
	int obj = JArray.getObj(object, i)
	
	Form base = JMap.getForm(object, "SomeKey.Form")
	
	;Placement stuff
	
	;The important bit
	if base == chestRep
		;Store the base somehow
		chestArray[c] = base
		chestArray[c].GetBaseObject().SetName("chest" + (c + 1))
		chestArray[c].SetDisplayName("Chest", true)
		
		c += 1
	endif
		
	
	i += 1
endwhile

And the next is a mostly functional activator script snippet.

ObjectReference[] Property chest_ Auto

string name

Event OnInit()
	name = self.GetBaseObject().GetName()
EndEvent

Event OnActivate(ObjectReference ref)
	string index = ""

	int i = 0

	if StringUtil.GetLength(name) == 5
		index = "0"
	elseif StringUtil.GetLength(name) == 6
		index = Substring(name, 5)
	elseif StringUtil.GetLength(name) == 7
		index = Substring(name, 5)
	endif

	int final_I = index as int
	
	if ref == Game.GetPlayer() && final_I != -1
		chest_[final_I].Activate(ref)
	endif
EndEvent

For others that may be reading this, consider this a warning: I didn't go out of my way to make any of these scripts drag-and-drop usable, as they are just for demonstration.


Thanks again for the responses!

 

Edited by MatthiosArcanus
Link to comment
Share on other sites

Hey, thanks so much everyone for your responses!

 

Mattiewagg, you can fill properties dynamically, like in script as opposed to statically in the Creation Kit? I never knew that, and could be quite useful. You're talking about properties such as "ObjectReference Property test Auto?"

<snippity snip>

 

Yep. Properties can be assigned and changed just like variables in this way.

 

If it's working for you at the moment, fantastic - and I'd say stick with it unless you can think of another way to do it, or there are issues with your version in terms of performance or something.

Link to comment
Share on other sites

I've modified an existing script that someone made for me a while ago. When you click on an activator, 4 firewood is removed from your inventory and a fire is enabled. It will disable itself after 8 hours. Here it is...

 

 

 

Scriptname SCFireLight extends ObjectReference

 

ObjectReference Property FireXMarker Auto

MiscObject Property Firewood01 Auto

Float fTimeIgnited

Float fCurrentTime

 

Event OnActivate(ObjectReference akActionRef)

If (Game.GetPlayer().GetItemCount(Firewood01) >= 4)

Game.GetPlayer().RemoveItem(Firewood01, 4)

FireXMarker.enable()

fCurrentTime = Utility.GetCurrentGameTime()

fTimeIgnited = fCurrentTime

Else

Debug.Notification("You Need 4 Pieces Of Firewood")

EndIf

EndEvent

 

Event OnCellAttach()

fCurrentTime = Utility.GetCurrentGameTime()

If fCurrentTime > (fTimeIgnited + 0.33)

FireXMarker.disable()

EndIf

EndEvent

 

 

 

I have tested it and everything seems to be working. Questions...

 

1) Are there any potential problems with the script?

2) Is there any way I can make the script update periodically? At the moment it only updates when the cell is entered.

3) Is there a way of updating it when a player sleeps in the same cell?

1) I think it's fine.

2) Yep, we're going to use a function called RegisterForSingleUpdate (in particular, the GameTime version). Linky

3) Updating the time? The method with Updates will work fine to take care of this, but you can always register for sleep on the player alias (requires a quest) if you need it for something else.

 

Here is your revised script, using the new method:

Scriptname SCFireLight extends ObjectReference  

ObjectReference Property FireXMarker Auto
MiscObject Property Firewood01 Auto
Actor Property PlayerREF Auto; if using the player's reference more than once, use a property for increased efficiency compared to GetPlayer
;this will autofill

Event OnActivate(ObjectReference akActionRef)
    If (PlayerREF.GetItemCount(Firewood01) >= 4)
        PlayerREF.RemoveItem(Firewood01, 4)
            FireXMarker.enable()
            RegisterForSingleUpdateGameTime(8.0); let's check in 8 game hours from now
    Else
            Debug.Notification("You Need 4 Pieces Of Firewood")
    EndIf
EndEvent

Event OnUpdate()
    FireXMarker.Disable()
EndEvent
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...