Jump to content

Detecting crafting and workbench type.


Recommended Posts

I want to be able to detect that the player has started crafting and what crafting type it is. I have so far managed to use OnMenuOpen to detect the crafting menu, but I am at a loss how to detect whether it is smithing, alchemy etc.

I need to know what the crafting type is before an item is crafted (otherwise there is a story manger event for that).

I can put the RegisterForMenu("Crafting Menu") in either an magic effect on the player or on a player alias in a quest.

 

diziet

Link to comment
Share on other sites

An early version of my Inventory Management System mod used the OnCrosshairRefChange event to catch when the player pointed the crosshair at the workstations. Depending upon the workstation appropriate materials would transfer to the player. While it worked, it is a troublesome event to work with. The reason being is that every time the crosshair points at something different, the event will be triggered. Without a combination of conditions to block processing and using states to prevent processing altogether, the event will trigger unnecessarily.

 

What I ended up using was a hot key that when pressed would use GetCurrentCrosshairRef and then transfer the appropriate materials based on whether the reference's base form matched those in pre-defined lists.

 

I also experienced during testing that the current crosshair ref can change as the initial rotation animation plays underneath the crafting menu as it opens up. Thus storing the initial crosshair ref in a local variable is necessary.

 

You could attempt to use GetCurrentCrosshairRef after the crafting menu is opened. But I have no idea if it will still get a reference with the menu open. And if it does, there is no guarantee that it will be the workstation at the crosshair point.

 

You could also try the OnSit event to at least catch those workstations that are furniture rather than activators.

Link to comment
Share on other sites

I had hoped that there might be unique animations for crafting but I couldn't find any:) And I was surprised that doesn't seem to be an event for theplayeractivatedsomething(ObjectRef the thingthatwasactivated). I will try your GetCurrentCrosshairRef and see how reliable it is, thanks.

 

diziet

 

edit: not bad, except for alchemy labs! And of course there is always the possibility of custom workbenches. Do you kow what the animation for the alchemy lab is?

Link to comment
Share on other sites

You could "break" everyone's game and put a script directly on the workstation base that informs your mod of which type of workstation it might be. But then, instead of including that in your mod, a base mod could be made that will share what crafting station is being interacted with. This could be released as a separate mod and if done right won't truly break a user's game though it would still be incompatible with other mods that modify the same base object.

 

I'm thinking of something like the following:

 

attached to the base record of each crafting station - will need "patches" for every mod that adds new base record stations

 

Event OnActivate(ObjectReference akActivator)
  If akActivator == Game.GetPlayer() ; only care if it is the player
    String myLabel = "Alchemy" ; change as needed
    SendModEvent("abim_CraftStationCheck",myLabel)
  EndIf
EndEvent

Note - a property would be better for the above as the script could then be reused as many times as needed. However, properties get baked into the save file and we do not want that if the mod needs to be removed. Instead, just create a separate version of the script for each station with the text label defined locally.

 

Within scripts needing to receive the event

 

Event OnInit()
  MaintUpdate()
EndEvent
 
Function MaintUpdate() ;also call this function, remotely if need be, from the OnPlayerLoadGame event within a player alias script
  RegisterForModEvent("abim_CraftStationCheck","OnCraftActivate")
EndFunction
 
Event OnCraftActivate(string eventName, string strArg, float numArg, Form sender)
  If eventName == "abim_CraftStationCheck" ; just in case another mod uses the same custom event name for a different purpose
    If strArg == "Alchemy"
      ;do something
    ElseIf strArg == "Cooking"
      ;do something
    ;etc... etc...
    EndIf
  EndIf
EndEvent

 

 

 

 

All that said, it may be possible to utilize an SKSE DLL plugin to determine the station being interacted with at the engine level and thus not be tied to the papyrus level. But that is beyond my knowledge.

Link to comment
Share on other sites

Cant you use keywords?

 

If objectactivated.haskeyword(isenchanting); for example

 

Pretty sure all the crafting furnitures have keywords like isenchanting that determines what animation to play on entering.

 

Where to check for this is a trickier problem though I guess, as you dont want to be putting it on the furniture themselves I presume.

 

Maybe Game.FindClosestReferenceOfTypeFromRef can help?

 

Sorry if this helps none. Just throwing ideas.

Edited by TyburnKetch
Link to comment
Share on other sites

You beat me to my post! I have made a quest that runs when the Crafting Menu is opened, it has an alias:

https://i.imgur.com/veNuCpP.png

the script that launches it is:

 

 

Scriptname dz_outfits_crafting_effect_script Extends ActiveMagicEffect

Quest Property workbench_quest  Auto
ReferenceAlias Property workbench Auto
Actor Property PlayerRef AutoEvent OnEffectStart(Actor akTarget, Actor akCaster)
dz_mcm.DEBUG_TRACE(PlayerRef,"crafting effect has started")
    Utility.Wait(1)
    RegisterForMenu("Crafting Menu")
EndEvent
Event OnEffectClose(Actor Target, Actor Caster)Endevent
Event OnMenuopen(String menuName)
GoToState("Busy")
    If menuName == "Crafting Menu"
  workbench_quest.Start()
  dz_mcm.DEBUG_NOTIFY(PlayerRef,"started crafting")
  dz_mcm.DEBUG_NOTIFY(PlayerRef,"cross hair ref is "+Game.GetCurrentCrosshairRef().GetBaseObject().GetName())
  dz_mcm.DEBUG_NOTIFY(PlayerRef,"detected workbench alias is "+workbench.GetRef().GetBaseObject().GetName())
  
    Endif
GoToState("")
EndEventEvent OnMenuClose(String menuName)
GoToState("Busy")
    If menuName == "Crafting Menu"
  workbench_quest.Stop()
  dz_mcm.DEBUG_NOTIFY(PlayerRef,"finished crafting")
 
    Endif
GoToState("")
EndEvent

State Busy
Event OnMenuOpen(String menuName)
;;;these 2 functions can get called in rapid succession in any order
;debug.notification("Busy: skipping OnMenuClose - "+this_npc.GetDisplayName());;;
EndEventEvent OnMenuClose(String menuName)
EndEvent
EndState

 


minimal testing so far has it working, though I think that I will have to then retest tyhe workbench refalias for what keyword it has, as sometimes the 'name' for the crafting bench is just 'workbench' and of course mod added crafting stations could have any name.

It seems odd that the smithing and tanning stations have keywords for the type of station, but alchemy and enchanting don't.

In reference to IsharaMeradin's comment on the crosshair ref not being accurate due to animation, this has become more obvious during testing, sometimes it is even a passing NPC!

But the workbench alias filling still worked. Of course there is an assumption that since the crafting menu has opened, the nearest item with the keywords will be the crafting station; I'm not sure if that will always hold up:)

 

diziet

Link to comment
Share on other sites

If you do not mind making patches for mods that add new crafting areas, put a trigger volume box around the crafting area. Use this trigger volume box to determine what crafting station is in use and send that information to wherever you might need it. This would at least limit the event to running while inside the volume box rather than all the time. You would still need to take care with the conditions to ensure the crosshair ref is a valid crafting station and not something else like a nearby container.

 

I would do something like:

 

 

script on the trigger volume box

Int InTrigger = 0
 
Event OnTriggerEnter(ObjectReference akActionRef)
  If InTrigger == 0
    If akActionRef == Game.GetPlayer()
      InTrigger += 1
      RegisterForCrosshairRef()
    EndIf
  EndIf
EndEvent
 
Event OnTriggerLeave(ObjectReference akActionRef)
  If InTrigger > 0
    If akActionRef == Game.GetPlayer()
      InTrigger -= 1
      UnRegisterForCrosshairRef()
    EndIf
  EndIf
EndEvent
 
Event OnCrosshairRefChange(ObjectReference Ref)
  ;determine what type of station Ref might be
  ;use remote linking to run a function on your more persistent script
  ;use that function to do whatever you need with the knowledge of workstation type
EndEvent

 

 

 

EDIT: You posted while I was typing this up which explains why I had to reload the page to see my post... At any rate, take care with those keywords. I am pretty certain that those keywords also govern the animation used when activating. I recall playing around with them to get a custom station to once have an animation from one station with the interface type of a different station. It may be a rare occurrence but could be possible that you'll get some incorrect results with some custom stations.

Edited by IsharaMeradin
Link to comment
Share on other sites

Having identifed (hopefully) that the player is using a crafting station, my goal is to know what kind of crafting so that i can auto-equip the player with items with enhancements for that crafting. I don't yet know if equipping after the craft menu opens makes a difference to the crafting - my next test - but I do know that you can equip after the menu opens.

 

Looking at the use info for the keywords I've chosen it seems (in vanilla game anyway) that pretty much only crafting stations have them. Which begs the question of why there would be two keywords e.g.WICraftingEnchanting or isEnchanting only possessed by an enchanting station!

 

diziet

 

edit: does anyone kow offhand how and if I can check that smithing etc. is being enhanced using a worn item, is there a console command for that?

Link to comment
Share on other sites

Isenchanting is linked to the animation I believe.

 

Ishara has made a good point re: keywords. I myself have used the isenchanting keyword on a custom smelter, and also a custom oven, to get the player to use the animation used in vanilla for the enchanting table.

 

So care should def be taken with this approach.

Edited by TyburnKetch
Link to comment
Share on other sites

  • Recently Browsing   0 members

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