Jump to content

Weapon Damage Question


malonn

Recommended Posts

The following compiles but needs checking.

I have not worked out the weapon script and set/remove event handlers.

It will have to wait till I get back later on.

scn fnWeaponBooster

float fPercentile
float fAttribute
float fLuckMod
float fModifiedSkill
float fWeaponRating
float fHealthCurrent
float fHealthBase
float fAttackDamage
float fFatigueMod
float fSneakMultiplier
float fPowerAttackMultiplier
float fResistNormalWeapons
float fDamage

int iWeaponType
int iSneak

ref refWeapon
ref refAttacker
ref refTarget

begin function{fPercentile, refAttacker, refTarget}
	set refWeapon to refAttacker.getEquippedObject 16 ;16 is the weapon slot
	set iWeaponType to getWeaponType refWeapon
	set fLuckMod to 0.4 * ((refAttacker.getBaseActorValue Luck) - 50)

	if iWeaponType < 2 ;blade
		
		set fModifiedSkill to 0.2 + ((refAttacker.getBaseActorValue Blade) + fLuckMod) * 0.015
		set fAttribute to 0.75 + (refAttacker.getBaseActorValue Strength) * 0.005
		
	elseif iWeaponType < 4 ;blunt
		
		set fModifiedSkill to 0.2 + ((refAttacker.getBaseActorValue Blunt) + fLuckMod) * 0.015
		set fAttribute to 0.75 + (refAttacker.getBaseActorValue Strength) * 0.005
		
	else ;bow and staff (staff type is 4 but documentation does not allocate it.)
		
		set fModifiedSkill to 0.2 + ((refAttacker.getBaseActorValue Marksman) + fLuckMod) * 0.015
		set fAttribute to 0.75 + (refAttacker.getBaseActorValue Agility) * 0.005

	endif

	set fAttackDamage to getAttackDamage refWeapon
	set fHealthCurrent to getCurrentHealth refWeapon
	set fHealthBase to getObjectHealth refWeapon

;___Finally, weapon rating.
	set fWeaponRating to 0.25 * fAttackDamage * fAttribute * fModifiedSkill * (fHealthCurrent / fHealthBase + 1)


;	including 2 divider for final equation (as per documentation) here	
	set fFatigueMod to 0.5 * ((refAttacker.getBaseActorValue Fatigue) / (refAttacker.getActorValue Fatigue) + 1)

	set fPowerAttackMultiplier to 2.5
	if refAttacker.isSneaking
		set iSneak to refAttacker.getBaseActorValue Sneak
		if iWeaponType == 5 ;Bow
			if iSneak < 25
				set fSneakMultiplier to 2
			else
				set fSneakMultiplier to 3
			endif
		else ;The documentation's table lists all of this under One Handed - is it time to do a mod that allows Shield with Claymore?
			if iSneak < 25
				set fSneakMultiplier to 2
			else
				set fSneakMultiplier to 3
			endif
		endif
	else
		set fSneakMultiplier to 1
		if refAttacker.isPowerAttacking
			set fPowerAttackMultiplier to 3
		endif
	endif

	set fResistNormalWeapons to (100 - refTarget.getActorValue ResistNormalWeapons) * 0.01
	
	set fDamage to fWeaponRating * fFatigueMod * fSneakMultiplier * fPowerAttackMultiplier * refTarget.getArmorRating * fResistNormalWeapons
	
	setFunctionValue fDamage
end
Link to comment
Share on other sites

Okay. Thanks for the response. I will build from that script if it's needed. I'm curious though. Someone else said that because the formula is all multiplication, using "SetWeaponDamage" (and modifying it by the percentage of increase) will effectively give the formula a x% boost. Is that true?

Link to comment
Share on other sites

I have not found SetWeaponDamage in CS or OBSE documentation nor does it compile in the CSE script editor.
I may be wrong but it appears to be the OBSE "(nothing) reference.SetAttackDamage nuDamage:int objectID:ref"

If setting the percentage by formula as requested I think it would have to an event handler for onHitWith.
Correct me if wrong but that will set the attack damage after hitting the target.
If so then it would be imbalanced game play with either a an advantage or disadvantage from one target to the next.

In the end the OBSE setAttackDamage sets the Base damage.
Would setting that achieve the result you require.

scn myWeaponScript

int iDamage
ref refSelf

begin onEquip
	set refSelf to getSelf
	set iDamage to refSelf.getAttackDamage ;base damage regardless of 0 to n health
	set iDamage to iDamage * 1.6 ;or questname.fPercentile/whatever
	refSelf.setAttackDamage iDamage
end

I think that could be done as a function to be referenced by an event handler.
Or that it could be done as a magic effect script on an enchantment appended to a weapon.
If you already have your own weapon set for your mod then can you add a function call to each of their script that retrieves the percentile as suggested?

Link to comment
Share on other sites

You're right. My fault. It is "SetAttackDamage" not "SetWeaponDamage". I believe Event Handlers are processed just before the event occurs. So an "OnHealthDamage" event will trigger right before the the scripted ref takes damage. So it can be nullified in the script. "OnHitWith" will fire just before the target (or player -- whatever) gets hit. I think I'm going to store the default weapon damage in an array and mod it when the conditions are right. then restore it when they are wrong. I just wasn't sure about a true x% increase and how to accomplish it. So, do you think (as you understand it) that using "SetAttackDamage" will give damage a true x% increase, or will I have to use a formula?

Link to comment
Share on other sites

Sorry for being so verbose but you did ask what I think so...

Before I say anything about performance I realise that almost everyone playing Oblivion now have machines far more powerful than was entry level at time of release.
For me it is just a process of consideration, an old habit, that frequently provides something for nothing - or just a fun challenge if nothing else.

Let's separate the event from the handlers.
In this case the event is the collision between 2 objects, weapon and target.
The engine "Raises" an opportunity, "Event Handler" such as onHitWith, for us to "Bind" code to (a code window). SetEventHandler allows us to perform a dynamic binding as such.
The engine then resumes processing the result of the collision.
That process, as per wiki, is based on the weapon/parent and target properties.

Considering the sequence, it would seem there is an Opportunity to reference and/or manipulate properties of either objects/parent just prior to the latent processing - but is there?
Exposing the properties, as mentioned by the formulas on the wiki, at this time would require the engine to have specific latent error handling for the properties, manipulation and so on - considering battle pace and rendering I would expect more generic.
The wiki already states that Attribute and ModifiedSkill are constrained between 0 and 100.
The fastest processing we throw at the machine is...NONE!
Considering the entry gaming machines of the time it is possible the code is optimized to perform the calculation on the values as at time of collision. As such, anything else in the raised code would be arbitrary.

Even if the intervening manipulation affects the outcome of the collision I have to ask is it worth it?
The engine is going to perform the algorithms, as per wiki, in native code either way.
Performing a redundant scripted (interpreted) version would add undue overhead.
While I am not going to speculate on number of NPCs in a battle versus average hits it is worth bearing this overhead in mind.
It is only fair to consider how this may impact other mods that players want to use your weapons in.

As per documentation...

WeaponRating = BaseWeaponDamage * 0.5 * ( 0.75 + Attribute * 0.005 ) * ( 0.2 + ModifiedSkill * 0.015 ) * ( WeaponHealth / BaseWeaponHealth + 1 ) / 2

...OBSE...

SetAttackDamage - sets the base attack damage
(nothing) reference.SetAttackDamage nuDamage:int objectID:ref

...I'd be quite surprised if that isn't BaseWeaponDamage.
If so you can bind a generic function to onEquip and onUnEquip.

* Desired outcome, during battle, achieved using Existing Native Code!

I made a hasty response the first time as I had 20 minutes spare before work...

If it were my project I would unit test on SetAttackDamage first.
I would at least try to get it as close as I could to desired outcome.
If still unsure then cross test the 2 methods for performance as well as outcome.
I would do a binary search to find the optimal number of NPCs could fight it out in a cell for either method.
I'd try something like 20 (10 versus 10) and go up by 100% or down 50% until finding optimal number.
If the method with the scripted event addition did not have greater lag I would want to know why.
Any such optimization could be well worth taking advantage of.

Link to comment
Share on other sites

Interesting. I believe there is a runtime script impact OBSE plugin. Something that checks how long a script takes to process. It's out there. So what I'll do is test both with the formula you provided and check with just the OBSE function. See how close the results get of each to a true x% increase. Then I'll check the script impact. Go from there.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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