Auto Repair Script

Post » Sun Jan 30, 2011 6:18 am

Hello Guys

I started scripting a little script which Repairs the Armor of my NPC at 5 a.m

ScriptName Test2

begin GameMode
if GameHour == 5 && GetEquippedCurrentHealth 20 < 100
EquipItemNS 00homuraarmor ; equips armor, just in case its health is 0 and the NPC unequips it
SetEquippedCurrentHealth 100 20
endif
end


This armor occupies upper,lower,hand and foot slots, and I'm using OBSE functions.

I can compile it, but it doesn't work ingame.
Help plz!
User avatar
Steven Nicholson
 
Posts: 3468
Joined: Mon Jun 18, 2007 1:24 pm

Post » Sun Jan 30, 2011 12:27 am

The armor slot references are always confusing, but I suspect that will only repair Arena Rainment or the DB armor, being the ones that occupy all the four slots determined by the "20" (and maybe a few more like that). I.e. that statement probably is working as repair the item if it occupies "all of slot 20" rather than "any of slot 20".

You're probably going to need a complex if...elseif...endif structure around the SetEquippedCurrentHealth to check what slot values are appropriate for the item being repaired.
User avatar
Flash
 
Posts: 3541
Joined: Fri Oct 13, 2006 3:24 pm

Post » Sat Jan 29, 2011 4:10 pm

i think i haveto test now

how can i print the values of a var or a ref via player.message?

for example:
ref x
set x to GetArmor ; just a name
player.message x ; only print the name of the ref
User avatar
Arnold Wet
 
Posts: 3353
Joined: Fri Jul 07, 2006 10:32 am

Post » Sun Jan 30, 2011 1:49 am

Okay i solved that Problem.

Here's another one
I try to get the health of a certain Item in the Inventory of a NPC
I tried

short health
set health to"04000ED3".GetCurrentHealth ; 04000ED3 is just an example ID of that item
player.message "Health is: %.0f",health

but my script seems to crash because i don't get any message.

Can anyone help me?
User avatar
Eduardo Rosas
 
Posts: 3381
Joined: Thu Oct 18, 2007 3:15 pm

Post » Sat Jan 29, 2011 3:16 pm

Don't use the actual formid in scripts. Use the editorid instead. Suppose you load this mod in slot 5?
User avatar
Zach Hunter
 
Posts: 3444
Joined: Wed Aug 08, 2007 3:26 pm

Post » Sat Jan 29, 2011 9:43 pm

Where do I start?

First, the item in the inventory isn't the one you picked up. In fact, it isn't quite an item any more, but a reference back to the base formid for some details, and a few local things (like the health) saved in the list.

Second, your code is assuming that there can only be one instance of it in your inventory. This is not generally the case, although I grant you could be doing this for a genuine unique. You generally need to retrieve an array of inventory items to walk to the one you need (or first instance of it).

Third, you need a float for health, it often has a fractional part.

But after all that, I don't believe you can access the health of the item, while it is in inventory, but unequipped. Once you equip it, there's a GetEquippedCurrentHealth that takes a slot number. If it's dropped its refid will change to an "FF" one that you can access with GetPCLastDroppedItemRef and that is a valid target for a GetCurrentHealth check. But in inventory = in limbo for most things.
User avatar
remi lasisi
 
Posts: 3307
Joined: Sun Jul 02, 2006 2:26 pm

Post » Sat Jan 29, 2011 11:43 pm

...and one more thing.

GameHour is a float, so testing for == 5 is not a good idea, as it will probably never equal exactly 5. You'll need a > 5 test, plus a do once check.
User avatar
JAY
 
Posts: 3433
Joined: Fri Sep 14, 2007 6:17 am

Post » Sun Jan 30, 2011 12:55 am

Where do I start?
...
But after all that, I don't believe you can access the health of the item, while it is in inventory, but unequipped. Once you equip it, there's a GetEquippedCurrentHealth that takes a slot number. If it's dropped its refid will change to an "FF" one that you can access with GetPCLastDroppedItemRef and that is a valid target for a GetCurrentHealth check. But in inventory = in limbo for most things.

I agree with your three points, but you can access the health of items in the inventory, using OBSE 19's new Inventory Reference functions. By using those, GetCurrentHealth works. I use it in my http://www.tesnexus.com/downloads/file.php?id=32365 mod, but of course adds a couple of new layers of complicity. The use of this in Useful Houses, is to control repair, among them to have a Repair All button in the repair menu...
User avatar
naome duncan
 
Posts: 3459
Joined: Tue Feb 06, 2007 12:36 am

Post » Sat Jan 29, 2011 8:38 pm

Haven't got round to OBSE 19 yet, but I'm not surprised that hole was filled in.
User avatar
Scotties Hottie
 
Posts: 3406
Joined: Thu Jun 08, 2006 1:40 am

Post » Sun Jan 30, 2011 7:09 am

thx for the answers.
@ TheNiceOne i'll see what i can find in your mod :)
and can you name some of these new useful ref functions from OBSE19?

@ Ghastley is there an equivalent for NPCs with GetPCLastDroppedItemRef?

btw if an armor or weapon's health is 0 and the Doesn't wear it anymore does it count as unequipped?
User avatar
Emmanuel Morales
 
Posts: 3433
Joined: Sat Oct 06, 2007 2:03 pm

Post » Sat Jan 29, 2011 6:28 pm

thx for the answers.
@ TheNiceOne i'll see what i can find in your mod :)

I happened to have the most relevant script on a memory stick, so here it is:
Spoiler
ScriptName UHrepairAllshort hammersBrokenref itemfloat repair_limitfloat baseHfloat targetHfloat oldHfloat newHshort countBegin Function {}	let tnoUH.hammerWear += (tnoUH.repairAllSwings * tnoUH.hammerBreakChance)	let hammersBroken := Floor tnoUH.hammerWear	if hammersBroken		DebugPrint "UH:Hammer wear %.2f, broke %.0f hammer(s)", tnoUH.hammerWear, hammersBroken		PlaySound UIArmorWeaponRepairBreak		let tnoUH.hammerWear -= hammersBroken		Player.RemoveItemNS RepairHammer hammersBroken		let tnoUH.hammer_count -= hammersBroken		SetmenuFloatValue "hammer_number_text\user0", 1035, tnoUH.hammer_count	else		PlaySound UIArmorWeaponRepair	endif		ForEach item <- PlayerRef		if item.IsWeapon || item.IsArmor			let baseH := item.GetObjectHealth			if item.GetEnchantment				let repair_limit := tnoUH.enchanted_repair_limit			else				let repair_limit := tnoUH.current_repair_limit			endif						let targetH := baseH * repair_limit / 100.0			let targetH := Ceil targetH			let oldH := item.GetCurrentHealth			if targetH > oldH				item.SetCurrentHealth targetH				let count += item.GetRefCount				let newH := item.GetCurrentHealth				DebugPrint "UH:Repaired %n from %.0f to %.2f/%.2f, target %.0f", item, oldH, newH, baseH, targetH			endif		endif	Loop		let oldH := GetPlayerSkillUse Armorer	let baseH := player.GetAv Armorer	IncrementPlayerSkillUse Armorer, 0, tnoUH.repairAllSwings	let newH := GetPlayerSkillUse Armorer	let targetH := player.GetAv Armorer	DebugPrint "UH:Hammer swings %.0f, repaired %.0f items. Armorer skill increased from %.0f/%.0f to %.0f/%.0f", tnoUH.repairAllSwings, count, baseH, oldH, targetH, newHEnd

The middle part of the script (starting with "ForEach" loops through all armor/weapon in the inventory and increases their health up to a limit (different limit for enchanted and non-enchanted weapons). It is of course simpler if you just want to set the current health equal to base health.

and can you name some of these new useful ref functions from OBSE19?

Yes, just look up the http://obse.silverlock.org/obse_command_doc.html#Inventory_Reference section in the docs.
User avatar
kasia
 
Posts: 3427
Joined: Sun Jun 18, 2006 10:46 pm

Post » Sat Jan 29, 2011 7:34 pm

could you please tell me which value or functions
PlayerRef in your foreach loop has?
User avatar
Dawn Farrell
 
Posts: 3522
Joined: Thu Aug 23, 2007 9:02 am

Post » Sun Jan 30, 2011 5:43 am

This is from a quest script that is set to run once every second. No issues reported by users, effectively repairs all armor and weapons roughly every ten seconds.

Works with Obse 18 and greater.

Float RepairTessArmorVarint slotDGref itemDGint hlthDG;weapon and armor repair area;run this every 10 seconds or soif (RepairTessArmorVar > 10)	set RepairTessArmorVar to 0	set slotDG to 0		Label 10		set itemDG to AATessCompanionRef.getEquippedObject slotDG		set hlthDG to getObjectHealth itemDG		AATessCompanionRef.setEquippedCurrentHealth hlthDG slotDG		set slotDG to (slotDG + 1)		if (slotDG < 21 )			GoTo 10		endifelse	set RepairTessArmorVar to (RepairTessArmorVar + 1)endif


Code was derived from Romancing the Eyja mod and slightly modified, seems to work flawlessly.

Hope this helps
User avatar
Code Affinity
 
Posts: 3325
Joined: Wed Jun 13, 2007 11:11 am

Post » Sat Jan 29, 2011 7:16 pm

I have tested my script

ScriptName Testfloat ebenref armref zoestring_var homurabegin GameModelet zoe := getSelflet homura := "Homura oufit"if GetSleeping == 3    foreach arm <- zoe       let eben := arm.GetCurrentHealth        if arm.GetName == homura       player.message "Jackpot   +   %.0f", eben       endif   loopendifend


it show the current health of every item, in the npc inventory quite well.
Now i changed it. I want to repair a certain item, whether equipped or not.
so i tried
if arm.GetName == homura and homura is just a var for the editorid of that armor
but it doesnt work cause there seems to be a runtime error.

so can you give me a better solution to find my certain item in this loop?
or a better way to compare strings, which seems not to implemented in the standard cs
User avatar
sophie
 
Posts: 3482
Joined: Fri Apr 20, 2007 7:31 pm

Post » Sun Jan 30, 2011 9:32 am

Not sure if this will help or not, I haven tried it in this way before, but I've been messing with GetFirstRef and GetNextRef to cycle through all the items in a cell, apparently it works on inventory items too.

Heres a test script that might help, it's similar to what I'm using, will need altering a bit for what you want.

		;=== STAGE 1: Start scanning for first ref		if sScanRefs == 0			set rMyItems to GetFirstRef 70 ;=== Check for first ref, 70 being the code too look in inventory items			set sScanRefs to 1		endif		;=== STAGE 2: A ref has been found                if sScanRefs == 1 && rMyItems != 0                         if (Check if rMyItems ref is the name of the item you are looking for etc)                                (Do Stuff to your item if it is found)                                   set rMyItems to GetNextRef ;=== Check for next ref                                set sScanRefs to 2                        else ;=== Was not the item you are looking for			        set rMyItems to GetNextRef ;=== Check for next ref                                   set sScanRefs to 2		        endif                 endif		;=== STAGE 3: Another ref was found, loop back to STAGE 2                                                    		                if sScanRefs == 2 && rMyItems != 0			set sScanRefs to 1		endif		;=== STAGE 4: No refs found at all, scan finished		if sScanRefs == 1 && rMyItems == 0			set sScanRefs to 2		endif				;=== STAGE 5: Scan has finished (no more items found, either stop or loop back to STAGE 1)		if sScanRefs == 2 && rMyItems == 0			set sScanRefs to 1 ;=== Set to 0 to loop back to STAGE 1 again and start another scan		endif		endif

User avatar
john palmer
 
Posts: 3410
Joined: Fri Jun 22, 2007 8:07 pm

Post » Sun Jan 30, 2011 2:15 am

Not sure if this will help or not, I haven tried it in this way before, but I've been messing with GetFirstRef and GetNextRef to cycle through all the items in a cell, apparently it works on inventory items too.

Heres a test script that might help, it's similar to what I'm using, will need altering a bit for what you want.

		;=== STAGE 1: Start scanning for first ref		if sScanRefs == 0			set rMyItems to GetFirstRef 70 ;=== Check for first ref, 70 being the code too look in inventory items			set sScanRefs to 1		endif		;=== STAGE 2: A ref has been found                if sScanRefs == 1 && rMyItems != 0                         if (Check if rMyItems ref is the name of the item you are looking for etc)                                (Do Stuff to your item if it is found)                                   set rMyItems to GetNextRef ;=== Check for next ref                                set sScanRefs to 2                        else ;=== Was not the item you are looking for			        set rMyItems to GetNextRef ;=== Check for next ref                                   set sScanRefs to 2		        endif                 endif		;=== STAGE 3: Another ref was found, loop back to STAGE 2                                                    		                if sScanRefs == 2 && rMyItems != 0			set sScanRefs to 1		endif		;=== STAGE 4: No refs found at all, scan finished		if sScanRefs == 1 && rMyItems == 0			set sScanRefs to 2		endif				;=== STAGE 5: Scan has finished (no more items found, either stop or loop back to STAGE 1)		if sScanRefs == 2 && rMyItems == 0			set sScanRefs to 1 ;=== Set to 0 to loop back to STAGE 1 again and start another scan		endif		endif



can you or anyone give me an example for this condition in stage 2?

lets say my armors editorid is 00homura,the armors name itself is homura and my ref is simply called myItem.
i can't compare myItem== 00homura or 00homura == "homura"

what can i do?
User avatar
jessica Villacis
 
Posts: 3385
Joined: Tue Jan 23, 2007 2:03 pm


Return to IV - Oblivion