Jump to content

ModWeaponSpeed


cfh85

Recommended Posts

What I had in mind was to set the weapon as non playable. The ability will scan the NPCs inventory every 10minutes (maybe more), evaluate the weapons in the NPCs inventory. Of the ones that fit the right criteria (Bows for archers, any blade for swordsman etc) the script will pick the best one, if it's different from the last one it picked it will change the clone to match. It the unequips and re-equips the weapon so the changes take effect.

 

This will cause some issues. Firstly I don't think I can account for enchantments (I haven't looked into it yet) so currently it's just Damage, reach and speed.

Secondly if you change the NPCs weapons it may take 10 minutes to change - the alternative is to run the script more often, but I don't think it's too much of a problem.

Thirdly, when you reload the game it should (due to the way the functions work) revert back to the original clone, until the script runs and changes it.

 

the script I have so far, that needs finishing as I wrote it without internet access so I need to check/improve/finish lots of it

 

Scriptname CFHCompanionsClass13AbilityScript

;Knife Dancer - Lightning Speed

Ref Self
Ref Weapon1	;The base weapon.
Ref Weapon1Base
Ref Weapon2	;The current weapon the base is copying
Ref WeaponBase 	;Base object of original cloned weapon
Ref TempWeapon	;The new weapon to be copied
Ref InventoryItem

Float Timer
Float Counter
Float IISpeed
Float IIReach
Float IIDamage
Float IIRating
Float TempWeaponRating
Float Level
Float SpeedMod
Float Fame
Float Infamy
Float Renown

Begin ScriptEffectUpdate
If Timer > 0
	Set Timer to (Timer - GetSecondsPassed)
	Return
Else
	USE ARRAY TO SEE WHAT ITEMS ARE IN THE NPCS INVENTORY

	While Counter > 0
		Let Counter -= 1

		If (InventoryItem.IsWeapon == 0)
			Continue
		ElseIf (InventoryItem.GetWeaponType != 0)
			Continue
		ElseIf ((GetWeaponReach InventoryItem) > 0.7)
			Continue
		Else
			Set IISpeed to (GetWeaponSpeed InventoryItem)
			Set IIReach to (GetWeaponReach InventoryItem)
			Set IIDamage to (GetAttackDamage InventoryItem)
			Set IIRating to (IIDamage * IISpeed * IIReach * IIReach)
			If IIRating > TempWeaponRating
				Set TempWeapon to InventoryItem
				Set TempWeaponRating to IIRating
			EndIf
		EndIf

		SET NEXT REFERENCE
	Loop

	If TempWeapon == Weapon2
		Set Timer to 600
		Return
	Else
		Set Fame to GetPCFame
		set Infamy to GetPCInfamy
		Set Renown to (Fame + Infamy)
		Set Level to (Self.GetFactionRank CFHCompanionLevelFaction)
		If (Level > (Renown / 3))
			Set Level to (Renown / 3)
		EndIf
		Set SpeedMod to (1 + (Level / 50))
		SETMODELPATH
		Set IISpeed to ((GetWeaponSpeed TempWeapon) * SpeedMod)
		Set IIReach to (GetWeaponReach TempWeapon)
		Set IIDamage to (GetAttackDamage TempWeapon)
		SetWeaponSpeed IISpeed Weapon1
		SetWeaponReach IIReach Weapon1
		SetAttackDamage IIDamage Weapon1
		Self.UnequipItemNS Weapon1
		Self.EquipItemNS Weapon1
		Set Timer to 600
		Return
	EndIf
EndIf
End

Begin ScriptEffectStart
Set Self to GetSelf
Set Timer to 600

USE ARRAY TO SEE WHAT ITEMS ARE IN THE NPCS INVENTORY

While Counter > 0
	Let Counter -= 1

	If (InventoryItem.IsWeapon == 0)
		Continue
	ElseIf (InventoryItem.GetWeaponType != 0)
		Continue
	ElseIf ((GetWeaponReach InventoryItem) > 0.7)
		Continue
	Else
		Set IISpeed to (GetWeaponSpeed InventoryItem)
		Set IIReach to (GetWeaponReach InventoryItem)
		Set IIDamage to (GetAttackDamage InventoryItem)
		Set IIRating to (IIDamage * IISpeed * IIReach * IIReach)
		If IIRating > TempWeaponRating
			Set TempWeapon to InventoryItem
			Set TempWeaponRating to IIRating
		EndIf
	EndIf

	SET NEXT REFERENCE
Loop

Set Weapon2 to TempWeapon
Set WeaponBase to Weapon2.GetBaseObject
Set Weapon1Base to CloneForm WeaponBase

MOVE A REF OF WEAPON1BASE INTO NPCS INVENTORY, SET WEAPON1 AS REF AND EQUIP ITEM
End

 

 

EDIT

I think this is the array function I need to use GetItems . It says about using form types to restrict the results. Not to sure about form types, could I set it to only return weapons?

Edited by cfh85
Link to comment
Share on other sites

Wouldnt you be much better off using an OnAdd Event handler? It would remove a lot of those problems and streamline the entire process. No arrays either. It would allow you to just draw the variable straight from the event instead of evaluating the entire contents of someones inventory.

 

But yes, the form codes for OBSE commands are listed on the OBSE documentation website.

Link to comment
Share on other sites

You misunderstand. Not an OnAdd block, but an OnAdd Event Handler. Event Handlers are independent scripts.

 

Event Handlers run whenever the "event" that you state occurs in game. For example, I could make an event handler that runs whenever NPC X uses a healing spell, or when the player is hit, or when a type of guard sees a murder. They don't have a source like other scripts, as in a quest, object or magic effect - they're just there, running only when needed. Not only that, but the parameters of an event can be passed to the Event Handler script directly as arguements, removing a lot of the checks you would normally need. For example, going back to the event where the player is hit, I can obtain a reference to the attacker by passing the arguement to the Event Handler.

 

You would be better off reading it from the OBSE website. They'll explain better than I will.

Edited by WarRatsG
Link to comment
Share on other sites

I had read some of the command documentation for V0020 and have since double checked and there is nothing on there for OnAdd.

 

There is a lot in there that I need to add into my scripts. Every time I feel like I'm making progress with this mod I get more work to do :facepalm: though (primarily thanks to your help) I am learning a lot of things to improve my mod.

 

I think I've got the idea of the event handlers, I just can't find the parameters for OnAdd. Would it be actor.ref item.ref ?

Link to comment
Share on other sites

You're right, there is no OnAdd Event. My apologies - since a lot of them matched standard blocktypes, I assumed OnAdd was among them. :rolleyes:

 

So if we back up a little bit...

 

 

GetItems seems like the best way to go. The form code for weapons is 33.

 

Enchantments can be modified. You can find most of the related functions here. Note that Enchantments count as Magic Effects, so some of the functions you need may not specifically refer to enchantments.

 

Without event handlers, the 10 minute wait problem remains. There is a solution, although it isn't quite clear yet. I recommend you look into User-Defined Functions as one possible solution. My first thought would be to switch on a bool in a gamemode blocktype, on the frame that the companions inventory is opened. This would prevent the gamemode block from running until the inventory window is closed. When it does close, the gamemode block immediately detects the switched on bool and uses the UD function to run all the checks, then switches off the bool. ScriptEffectUpdate blocks would probably work too.

 

Instead of using SetModelPath, you may prefer:

CopyModelPath - sets the model path of the calling reference or passed objectID to the model path from Object
(nothing) reference.CopyModelPath fromObject:ref toObject:ref

 

 

I really should just let you mod how you like, instead of backseat driving like this :P So long as you're learning something I guess 8)

Link to comment
Share on other sites

The event handlers look fantastic, though limited for what I'm doing (primarily because I want my mod to be used in the same was a CM Partners is, by other modders) as the abilities are each given to several NPCs, so I can't filter it much. The one I have used is OnRelease as it's the only way I've found to detect when an NPC shoots an arrow.

I'll read up on the user defined functions.

 

This ability has flaws in the way it's implemented, some of the others I'm still unsure of where to start, so help and advice is always welcome

Link to comment
Share on other sites

This is the script I've got so far. I plan on using it a topic instead that will add the NPC to a faction used to trigger certain abilities, this will allow the script to run as the first 'if' in scripteffectupdate will be GetInfaction...return, once the NPC has chosen the new weapon to copy it will remove itself from the faction. Also I'll move most of the script into a UD function.

 

I'm pretty sure these updates will be quick and easy and make it more efficient

 

 

Scriptname CFHCompanionsClass13AbilityScript

;Knife Dancer - Lightning Speed

Array_var Weapons

Ref Self
Ref Weapon1 ;The base weapon.
Ref Weapon1Base
Ref Weapon2 ;The current weapon the base is copying
Ref WeaponBase ;Base object of original cloned weapon
Ref TempWeapon ;The new weapon to be copied
Ref InventoryItem

Float Timer
Float IISpeed
Float IIReach
Float IIDamage
Float IIRating
Float TempWeaponRating
Float Level
Float SpeedMod
Float Fame
Float Infamy
Float Renown
Float Equip

Short Key

Begin ScriptEffectUpdate
If Equip == 1
Self.EquipItemNS Weapon1
Set Equip to 0
EndIf
If Timer > 0
Set Timer to (Timer - GetSecondsPassed)
Return
Else
Let Weapons := (Self.GetItems 33)
Let Key := ar_Size Weapons

While Key > 0
Let Key -= 1
Let InventoryItem := Weapons[Key]

If (InventoryItem.IsWeapon == 0)
Continue
ElseIf (InventoryItem.GetWeaponType != 0)
Continue
ElseIf (InventoryItem == Weapon1)
Continue
ElseIf ((GetWeaponReach InventoryItem) > 0.7)
Continue
Else
Set IISpeed to (GetWeaponSpeed InventoryItem)
Set IIReach to (GetWeaponReach InventoryItem)
Set IIDamage to (GetAttackDamage InventoryItem)
Set IIRating to (IIDamage * IISpeed * IIReach * IIReach)
If IIRating > TempWeaponRating
Set TempWeapon to InventoryItem
Set TempWeaponRating to IIRating
EndIf
EndIf
Loop

If TempWeapon == Weapon2
Set Timer to 600
Return
Else
Set Fame to GetPCFame
set Infamy to GetPCInfamy
Set Renown to (Fame + Infamy)
Set Level to (Self.GetFactionRank CFHCompanionLevelFaction)
If (Level > (Renown / 3))
Set Level to (Renown / 3)
EndIf
Set SpeedMod to (1 + (Level / 50))
Weapon1.CopyModelPath TempWeapon
Set Weapon2 to TempWeapon
Set IISpeed to ((GetWeaponSpeed TempWeapon) * SpeedMod)
Set IIReach to (GetWeaponReach TempWeapon)
Set IIDamage to (GetAttackDamage TempWeapon)
SetWeaponSpeed IISpeed Weapon1
SetWeaponReach IIReach Weapon1
SetAttackDamage IIDamage Weapon1
Self.UnequipItemNS Weapon1
Set Equip to 1
Set Timer to 600
Return
EndIf
EndIf
End

Begin ScriptEffectStart
Set Self to GetSelf
Set Timer to 600

Let Weapons := (Self.GetItems 33)
Let Key := ar_Size Weapons

While Key > 0
Let Key -= 1
Let InventoryItem := Weapons[Key]

If (InventoryItem.IsWeapon == 0)
Continue
ElseIf (InventoryItem.GetWeaponType != 0)
Continue
ElseIf ((GetWeaponReach InventoryItem) > 0.7)
Continue
Else
Set IISpeed to (GetWeaponSpeed InventoryItem)
Set IIReach to (GetWeaponReach InventoryItem)
Set IIDamage to (GetAttackDamage InventoryItem)
Set IIRating to (IIDamage * IISpeed * IIReach * IIReach)
If IIRating > TempWeaponRating
Set TempWeapon to InventoryItem
Set TempWeaponRating to IIRating
EndIf
EndIf
Loop

Set Weapon2 to TempWeapon
Set WeaponBase to Weapon2.GetBaseObject
Set Weapon1Base to CloneForm WeaponBase
Set Weapon1 to (Self.PlaceAtMe Weapon1Base 1, 0, 0,)
Weapon1.Activate Self
Self.EquipItem Weapon1
End[/Code]

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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