Item Durability structure

Post » Sun Jun 17, 2012 10:10 pm

Hi, i'm a superfan of item durability, so i'm seeing how to implement that on skyrim. Since oblivion and fallout have a durability system, i'm wondering if is still there hidden somewhere (i found only "getitemhealthpercent()" in ObjectReference).
User avatar
sally R
 
Posts: 3503
Joined: Mon Sep 25, 2006 10:34 pm

Post » Sun Jun 17, 2012 9:44 pm

burp... ehm... bump
User avatar
Emily Shackleton
 
Posts: 3535
Joined: Sun Feb 11, 2007 12:36 am

Post » Mon Jun 18, 2012 1:36 am

Hi, I'm no Pro though I might have an idea how to do this.

Inside the Object Window -> Items -> Weapons -> WEAPONS, if you find a weapon there and double click it, a new window pop up and you can see the area with Scripts.

I think if you create a script for a weapon, give it an integer variable value 100, 100 for maximum durability.
And then if you somehow can catch a weapon event, if it hits or if its being used you could decrease that value by X each time the event occur and use an if condition to check if the value is above 0.

And if its 0 or below, something should happen, removing the item, or a message, thats up to you :smile:

If this is possible, I don't know, I have not tried it but it seems logical enough :smile:
User avatar
Phillip Brunyee
 
Posts: 3510
Joined: Tue Jul 31, 2007 7:43 pm

Post » Mon Jun 18, 2012 10:41 am

Hi, I'm no Pro though I might have an idea how to do this.

Inside the Object Window -> Items -> Weapons -> WEAPONS, if you find a weapon there and double click it, a new window pop up and you can see the area with Scripts.

I think if you create a script for a weapon, give it an integer variable value 100, 100 for maximum durability.
And then if you somehow can catch a weapon event, if it hits or if its being used you could decrease that value by X each time the event occur and use an if condition to check if the value is above 0.

And if its 0 or below, something should happen, removing the item, or a message, thats up to you :smile:

If this is possible, I don't know, I have not tried it but it seems logical enough :smile:
tnx!
i'll try to implement the durability via script. Now i've to find the right event to run the function ;)
User avatar
Nick Tyler
 
Posts: 3437
Joined: Thu Aug 30, 2007 8:57 am

Post » Mon Jun 18, 2012 9:23 am

I have also tried to make this script without succes yet, though I might come close to which events we are looking for.

OnCombatStateChanged - Actor | I think this is a on time event fired every time the actor goes into a combat stance
OnAnimationEvent - Form | I think this is the right one, changing the durability each time the weapon is swinged or fired.
User avatar
Natasha Callaghan
 
Posts: 3523
Joined: Sat Dec 09, 2006 7:44 pm

Post » Mon Jun 18, 2012 7:03 am

OnAnimationEvent is the right one for the Bow, but it occurs on miss too. maybe a check on skill progression (one-hand, two-hand... ect) can be a nice idea for melee and armor, but i don't know if it exists.
User avatar
April
 
Posts: 3479
Joined: Tue Jun 20, 2006 1:33 am

Post » Mon Jun 18, 2012 1:01 pm

For the bow - I guess a bow's durability would decrease even if the arrow miss the target since the bow is still being used.

The armor - I found this on the Creation Kit wiki
OnHit - ObjectReference Soif you make a script on the player with OnHit event it should fire each time the player gets hit, the problem now is getting the armor the player is wearing to decrease the armor durability, I have found its possible to get the weapon, spell, shout, shield through the Actor but nothing on how to get the armor.

On the melee weapons I still cannot find anything usefull, though I have found some Havok Animations, if you in the Object Window go to Actors and Actor and Actor (again) and double click an actor a window will pop up, click on the tab Animation, there is a list of Havok Animations, it seems these are the real attacking, defending and much more animations, but I don't think these animations fires any events.
User avatar
Shannon Marie Jones
 
Posts: 3391
Joined: Sun Nov 12, 2006 3:19 pm

Post » Mon Jun 18, 2012 3:09 am

Yes, you are right about the bow. I think "bow_release" can work.

But for melee there are tons of animation for every stance and weap type. And there is a problem with missed attacks. An idea is to place it on "Onhit" of enemies, but then u need to add it to every actor.

About the armor... that's a problem... if we can't "get" the object, we can't do nothing :(

I hope to find something else while exploring the CK the next days
User avatar
Lavender Brown
 
Posts: 3448
Joined: Tue Jul 25, 2006 9:37 am

Post » Mon Jun 18, 2012 8:28 am

Update: i've an early and working version for melee weapon of the player, but i had to modify the base script "Weapon"
Added to Weapon
int Property HP = 1 autoFunction Damage()HP -= 1debug.notification("Ho ora " + HP + " HPs")EndFunction
damage will have a parameter to damage different amount of hp

Script assigned to Mob
Scriptname _mobHit extends ObjectReferenceEvent OnHit(Objectreference cane, form source, Projectile proiettile, bool pa, bool sa, bool ba, bool hb)if (cane == game.getplayer())  if (game.getplayer().getequippedweapon() == source)   game.getplayer().getequippedweapon().damage()  EndIfEndifEndEvent

then, i've assigned a script to the weapon
Scriptname WeaponExt extends Weapon
to set the HP property from the editor for the weapon
User avatar
LijLuva
 
Posts: 3347
Joined: Wed Sep 20, 2006 1:59 am

Post » Mon Jun 18, 2012 8:16 am

I forgot to update this topic. The script in my prev post does not work, because Weapon extends Form, so there are no information stored on the reference, but just on the base object. U need to attach a script to weapons and use that, but OnHit still returns the base obj, not the reference. So i register (point to them) on the player every script attached to items equipped on him. Still working on...
User avatar
Stephanie I
 
Posts: 3357
Joined: Thu Apr 05, 2007 3:28 pm

Post » Mon Jun 18, 2012 9:12 am

I have been working on my own solution to this very problem. GetItemHealthPercent only returns a value if the item is persistent. As a lot of stuff isn't, and for good reason, this is a no go. The best I have come up with is system whereby I hold the current "health" of each Weapon type I Equip in an array. This means that if I have 5 Iron Daggers but no way to tell them apart because they are not persistent, I have 1 "Health" value for all of them as a collection. I cannot unequip a worn dagger and equip a healthy one.

I am finding this acceptable except when one of the those daggers has been improved with smithing. I have 4 daggers and 1 Fine Dagger but I cannot tell them apart in script.

Persistence would seem to be the key, then you could put a script on each object and then, where you have 5 daggers, you have 5 versions of the script running; each with their own health being tracked. I have spent a lot of time trying to get that to work but the only way to get the weapons persistent is to drop them on the floor and pick them up again. And that only works if there is a script on them in the first place.

On the subject of the GetItemHealthPercent, the game must know which dagger has been improved and which hasn't as it shows them separately in the inventory. It would be most helpful if this information was usable in the scripting.
User avatar
Emma-Jane Merrin
 
Posts: 3477
Joined: Fri Aug 08, 2008 1:52 am

Post » Mon Jun 18, 2012 11:17 am

My version uses an array to store the durability data in an activemagic effect on each actor - works but is very clunky - I also store the itemtypes in a FormList but have been trying to migrate this also to a local array.
http://skyrim.nexusmods.com/downloads/file.php?id=12841

I really hope that one day we'll be able to access ObjectReferences that are equipped - probably with SKSE. As you mention, the UI has access to more information than we can get - perhaps using the UI objects to get the data is feasible?

Anyway here's my source - took many hours to get this far, as I'm sure you can guess:

Spoiler
Scriptname ScarabDurabilityActorEffect extends ActiveMagicEffect;===============  PROPERTIES  ==========================================;Formlist  Property ScarabDurabilityTrackerFLST  AutoFloat	 Property DamagePerHit				 AutoFloat	 Property BaseDurability			   AutoFloat	 Property BreakPoint				   AutoFloat[]   Property DurabilityTracker			Auto HiddenForm[]	Property FormTracker				  Auto HiddenActor	 Property ThisActor					Auto HiddenWeapon	Property RightWeapon				  Auto HiddenWeapon	Property LeftWeapon				   Auto Hidden;===============  VARIABLES   ==========================================;Int	 DurableItemIndex;===============	EVENTS	==========================================;Event OnEffectStart(Actor akTarget, Actor akCaster)  ThisActor = Self.GetTargetActor()  Debug.Trace("ScarabDurability I am " + ThisActor + ", I have ScarabDurabilityActorEffect")  DurabilityTracker = new Float[128]EndEventEvent OnObjectEquipped(Form akBaseObject, ObjectReference akReference)  if akBaseObject as Weapon	Debug.Trace("ScarabDurability " + ThisActor + " just equipped weapon: " + akBaseObject)	GetEquippedWeapons()		if GetItemDurability(akBaseObject) < BreakPoint	  Debug.Trace("ScarabDurability " + ThisActor + " that one is broken: " + akBaseObject)	  ThisActor.UnEquipItem(akBaseObject, true, false)	  	endIf	  endIfEndEventEvent OnCombatStateChanged(Actor akTarget, int aeCombatState)  ReEquipWeapons()  if (akTarget == Game.GetPlayer())	if (aeCombatState == 0)	  Debug.Trace("ScarabDurability " + ThisActor + "We have left combat with the player!")	elseif (aeCombatState == 1)	  Debug.Trace("ScarabDurability " + ThisActor + "We have entered combat with the player!")	elseif (aeCombatState == 2)	  Debug.Trace("ScarabDurability " + ThisActor + "We are searching for the player...")	endIf  endIfEndEventEvent OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)  Debug.Trace("ScarabDurability " + ThisActor + " was hit by " + akAggressor + " with " + akSource)  ;Debug.Trace("ScarabDurability " + "let's damage our stuff ")  if (abPowerAttack || abHitBlocked)	Debug.Trace("It was a power attack or blocked - double damage")	DamageOurStuff(DamagePerHit * 2)  else	DamageOurStuff(DamagePerHit)  endIfEndEvent;===============  FUNCTIONS   ==========================================;Function GetEquippedWeapons()  RightWeapon = ThisActor.GetEquippedWeapon(false)  LeftWeapon  = ThisActor.GetEquippedWeapon(true)  if RightWeapon as Weapon	InitializeItemDurability(RightWeapon)  endif  if LeftWeapon as Weapon	InitializeItemDurability(LeftWeapon)  endif  Debug.Trace("ScarabDurability " + ThisActor + " is equipped with: " + RightWeapon + LeftWeapon)  DumpDurabilityData()EndFunctionFloat Function GetItemDurability(Form DurableItem)  DurableItemIndex = GetFormIndex(ScarabDurabilityTrackerFLST, DurableItem)  Return DurabilityTracker[DurableItemIndex]EndFunctionFunction InitializeItemDurability(Form DurableItem)  DurableItemIndex = GetFormIndex(ScarabDurabilityTrackerFLST, DurableItem)  if (DurableItemIndex >= 0)	Debug.Trace("ScarabDurability " + DurableItem + "already registered at " + DurableItemIndex)  else	ScarabDurabilityTrackerFLST.AddForm(DurableItem)	DurableItemIndex = GetFormIndex(ScarabDurabilityTrackerFLST, DurableItem)	Debug.Trace("ScarabDurability " + DurableItem + "now registered at " + DurableItemIndex)  endIf  if DurabilityTracker[DurableItemIndex] as Float	Debug.Trace("ScarabDurability " + "Durability of " + DurableItem + " tracked at " + DurableItemIndex + " data " + DurabilityTracker[DurableItemIndex])  else	Debug.Trace("ScarabDurability " + "Durability of " + DurableItem + " tracked at " + DurableItemIndex + " data " + DurabilityTracker[DurableItemIndex])	DurabilityTracker[DurableItemIndex] = BaseDurability  endifEndFunctionFunction DamageItem(Form DurableItem, Float DamageOfHit)  DurableItemIndex = GetFormIndex(ScarabDurabilityTrackerFLST, DurableItem)  ; randomise damage done up to DamagePerHit  DamageOfHit = DamageOfHit * Utility.RandomFloat()  Debug.Trace("ScarabDurability " + "Damaging " + DurableItem + " by " + DamageOfHit)  DurabilityTracker[DurableItemIndex] = DurabilityTracker[DurableItemIndex] - DamageOfHit  Debug.Trace("ScarabDurability " + "Durability of " + ThisActor + DurableItem + " = " + DurabilityTracker[DurableItemIndex])  ; chance to break is inverse of amount damaged  if Utility.RandomFloat(0.0, BaseDurability) < DurabilityTracker[DurableItemIndex]	Debug.Trace("ScarabDurability " + ThisActor + "running BreakItem " + DurableItem)	BreakItem(DurableItem)  endIfEndFunctionFunction BreakItem(Form DurableItem)  DurableItemIndex = GetFormIndex(ScarabDurabilityTrackerFLST, DurableItem)  Debug.Trace("ScarabDurability " + ThisActor + "Broken " + DurableItem)  ThisActor.UnEquipItem(DurableItem, true, false)  Debug.Trace("ScarabDurability " + ThisActor + "Dropping " + DurableItem)  ThisActor.DropObject(DurableItem)  ObjectReference BrokenItem = Game.FindClosestReferenceOfType(DurableItem, ThisActor.GetPositionX(), ThisActor.GetPositionY(), ThisActor.GetPositionZ(), 100.00)  BrokenItem.SetDestroyed()  Debug.Trace("ScarabDurability " + ThisActor + "Reset Counter " + DurableItem)  DurabilityTracker[DurableItemIndex] = BaseDurabilityEndFunctionFunction DamageOurStuff(Float DamageOfHit)  if RightWeapon as Weapon	DamageItem(RightWeapon, DamageOfHit)  endif  if LeftWeapon as Weapon	DamageItem(LeftWeapon, DamageOfHit)  endifEndFunctionFunction ReEquipWeapons()  if (RightWeapon as Weapon)	Debug.Trace("ScarabDurability " + ThisActor + " Unequipping: "+ RightWeapon)	ThisActor.UnEquipItem(RightWeapon)	Debug.Trace("ScarabDurability " + ThisActor + " Equipping: "+ RightWeapon)	ThisActor.EquipItem(RightWeapon)  endif  if (LeftWeapon as Weapon)	Debug.Trace("ScarabDurability " + ThisActor + " Unequipping: "+ LeftWeapon)	ThisActor.UnEquipItem(LeftWeapon)	Debug.Trace("ScarabDurability " + ThisActor + " Equipping: "+ LeftWeapon)	ThisActor.EquipItem(LeftWeapon)  endifEndFunctionFunction DumpArrayData(Float[] objects)  int currentElement = 0  while (currentElement < objects.Length)	Debug.Trace("ScarabDurability " + "Durability of " + ThisActor + currentElement + " = " + objects[currentElement])	currentElement += 1  endWhileEndFunctionFunction DumpDurabilityData()  int currentElement = 0  while (currentElement < FormTracker.Length)	if FormTracker[currentElement] as Form	  Debug.Trace("ScarabDurability " + ThisActor + "Durability of " + ScarabDurabilityTrackerFLST.GetAt(currentElement) + " is " + DurabilityTracker[currentElement])	endif	currentElement += 1  endWhileEndFunction; copied from http://www.creationkit.com/GetAt_-_FormListint Function GetFormIndex(FormList List, Form Member) global{Gets the index of Member in List. Returns -1 if not found}	if (!List.HasForm(Member))		Return -1	endif	int Index = 0	While (List.GetAt(Index) != Member)		Index += 1	EndWhile	Return IndexEndFunction
User avatar
Sylvia Luciani
 
Posts: 3380
Joined: Sun Feb 11, 2007 2:31 am

Post » Mon Jun 18, 2012 7:29 am

My mod was at a good point, but every test i made was with items spawned on the ground. Bad choice.... when i was testing merchants (yesterday), i discovered that all items spawned inside a container have not a reference, so scripts on them works one at a time per form :(
User avatar
Connor Wing
 
Posts: 3465
Joined: Wed Jun 20, 2007 1:22 am

Post » Mon Jun 18, 2012 4:28 am

ScarabMonkey, how are you handling the repair of worn and broken items?
User avatar
..xX Vin Xx..
 
Posts: 3531
Joined: Sun Jun 18, 2006 6:33 pm

Post » Mon Jun 18, 2012 10:57 am

@oss133 LOL... that's all I have to say.

Seriously though, basically I'm not - but then my script doesn't actually break anything - I really hate it too.
Can't really make a decent one of these until we can get the refID, or some other way to specify which version we need to damage. The main problem is that enchanted and enhanced (tempered) weapons can't be specified .

I have been wondering whether judicious use of 'move everything with this formID to another container while I have 1 equipped' might be a workaround... then we can be sure we are affecting the right one - assuming the move script can move the right/wrong ones.
User avatar
Taylor Thompson
 
Posts: 3350
Joined: Fri Nov 16, 2007 5:19 am

Post » Mon Jun 18, 2012 11:35 am

Yes, it's so very tricky. Every solution I think I come up with is blocked by another problem. My plan is to limit durability to specific items. I am currently sitting here making "Broken" and "Worn" copies of the the Weapons and Armour I intend to include. That way they will be fixable with recipes. But it limits me to only covering vanilla Items and is very time consuming.

OBSE eventually allowed me to do everything I wanted to do in one script on things like Multiple Enchantments. If SKSE delivers the same level of power, all this is going to get a lot easier.
User avatar
Brian Newman
 
Posts: 3466
Joined: Tue Oct 16, 2007 3:36 pm

Post » Mon Jun 18, 2012 12:40 am

I was thinking of taking the other tac ... So only enhanced tempered items could be damaged,... at least that is already coded on the items, then retempering would be the fix....
User avatar
Ernesto Salinas
 
Posts: 3399
Joined: Sat Nov 03, 2007 2:19 pm

Post » Mon Jun 18, 2012 3:04 am

The problem there will be that you cannot get the temper value in script if it's not a reference yet.

It seems a number of people are trying to mod this back in. It makes you wonder why Beth left it out.
User avatar
RObert loVes MOmmy
 
Posts: 3432
Joined: Fri Dec 08, 2006 10:12 am


Return to V - Skyrim