schlangster Posted May 27, 2011 Share Posted May 27, 2011 (edited) OK, before further cluttering our release thread in the beth forums with this, I might as well make use of this forum to get some fresh ideas :) When tweaking around values for body part multipliers and DT bleedthrough i once again thought how annoying it is that armor DT counts for the head as well, even if its completely unprotected. So I thought why not give it a try to implement something that adds some extra damage for headshots if the head is unprotected, though I'm surely not the first to attempt this. First approach:Perk that does DT reduction if getHitLocation == 1, plus some more conditions to check for the absence of helmets etc. That would've been easy, but getHitLocation always returns -1 for this entry point. Second approach:Ammo effect script. getHitLocation works here, but the damage is already applied. So it would be possible to apply some fixed extra damage at least. Problem: Requires modification of every ammo record. I tried doing it dynamically with something like ref ammoScript set ammoScript to getScript DummyAmmo setScript ammoScript AmmoX but setScript didn't seem to work. Third approach:A challenge, with a reward script that runs after every headshot. GetCombatTarget could be used to get the tartget. Problem here is that a completion message is displayed after every shot. The message box can be temporarily disabled with setUIFloat, but since mutliple messages are queued you never really know when and how long it will be displayed. Talkie proposed polling the head condition, which works fine but as long as its >0, but then it can't detect changes anymore. So at this point, it seemed to me like there's no "simple" solution :( I accepted that any solution would probably not be feasible, at least some proof-of-concept would be nice. Approach 2 seemed worth pursuing since it at least allowed the detection of headshots without any negative side effects. But if every ammo entry has to be changed, then it better something more than just a static damage bonus. An effect script running on an actor could monitor its health, but it can't use getHitLocation. An ammo effect script has getHitlocation but no way to get the damage. That's why both are necessary: An effect script is added to nearby actors, which waits until a dummy effect is added by the ammo effect. This effect is active for one frame, just at the moment when the damage is done.The effect script then reverses the DT reductions to get original damage, and reduces enough health so it's as if there was no DT. Here's the script scn PNxRHeadshotMonitorEffectScript float lastHealth float damage float dam1 float dam2 ref helmet ;--------------------------------------- Begin ScriptEffectUpdate if getNumericGameSetting fMinDamMultiplier == 0 || getDead == 1 return endif ; Return unless headshot if isSpellTarget PNxRHeadshotSpell == 0 set lastHealth to getAV Health return endif printToConsole "Headshot!" ; Return unless DT > 0 if getAV DamageThreshold <= 0 set lastHealth to getAV Health return endif ; Return unless head is unprotected set helmet to getEquippedObject 9 if helmet != 0 if getArmorDT helmet > 0 set lastHealth to getAV Health return endif endif ; Apply extra damage if head is unprotected set damage to lastHealth - getAV Health if damage > 0 printToConsole "Real damage %.3f" damage ; Damage: 16, fMinDam 0.25 ; 16 * 0.25 = 4 > 16 - 15 = 1 ; 4 / 0.25 = 16 < 4 + 15 = 19 ; Damage: 24, fMinDam 0.25 ; 24 * 0.25 = 6 < 24 - 15 = 9 ; 9 / 0.25 = 36 > 9 + 15 = 24 set damage to damage / PNxRHeadshotDamMult set dam1 to damage / getNumericGameSetting fMinDamMultiplier set dam2 to damage + getAV DamageThreshold PrintToConsole "Min Dmg: %.3f vs Dmg: %.3f" dam1, dam2 if dam1 < dam2 PrintToConsole "Original damage was %.0f" dam1 set damage to (dam1 - damage) * PNxRHeadshotDamMult else PrintToConsole "Original damage was %.0f" dam2 set damage to (dam2 - damage) * PNxRHeadshotDamMult endif PrintToConsole "Extra damage: %.3f" damage damageAV Health damage endif endif set lastHealth to getAV Health End PNxRHeadshotDamMult is the body part multiplier for headshots. The ammo effect: scn PNxRHeadshotAmmoEffectScript Begin ScriptEffectStart if getHitLocation == 1 castImmediateOnSelf PNxRHeadshotSpell endif End And this worked really nicely, the real damage was accurately detected even with fMinDamMultiplier 0.01.So I thought what the hell, I'll just attach the ammo effect script to each ammo record. But when testing FPS suddenly dropped to 1 or so... seems like these ammo effect scripts run all the time, like an object script (i was carrying lots of ammo), even though they have no active block, the fact that they are processed is enough to kill the game. So the reason why I have written all of this :) : I'm looking for another way to tell the PNxRHeadshotMonitorEffectScript that a headshot happened, since the ammo effects can't be used. Any ideas? Basically any situation where getHitLocation returns something meaningful would be helpful. Dialogue combat topics didn't seem to work, maybe checking for hit animations?Hopefully someone has an idea cause I'd really like this to work.. Edited May 27, 2011 by schlangster Link to comment Share on other sites More sharing options...
AlexxEG Posted May 28, 2011 Share Posted May 28, 2011 (edited) You could attach the script to the player entry, and use the "Begin OnHit" to detect when the player been shot/hit It would be something like this I think:scn PNxRHeadshotAmmoEffectScript Begin OnHit if getHitLocation == 1 castImmediateOnSelf PNxRHeadshotSpell endif End Edited May 28, 2011 by Alexx378 Link to comment Share on other sites More sharing options...
TheTalkieToaster Posted May 28, 2011 Share Posted May 28, 2011 GetHitLocation doesn't return in player OnHit blocks- I tried using it in Impervious Power Armour in F3. Link to comment Share on other sites More sharing options...
schlangster Posted May 28, 2011 Author Share Posted May 28, 2011 (edited) Well, I think I got it working now. Since everything else failed, I was settling for the head condition polling in the same effect script that already does the health polling, but keeping the actors head condition above 0 all the time so it would still register changes, even if that means its no longer possible to cripple an enemies head.. you can't have everything :). While doing this I tried if it would be somehow possible to "break" something with setAV PerceptionCondition and weird values. After a bit of brute forcing, this seems to do the trick: set headCond to getAV PerceptionCondition ; Magic if headCond == 0 && lastHeadCond > 0 setAV PerceptionCondition -10 set headCond to -10 endif if headCond > 0 if lastHeadCond <= headCond set lastHeadCond to headCond set lastHealth to getAV Health return endif elseif headCond == lastHeadCond set lastHeadCond to headCond set lastHealth to getAV Health return endif set lastHeadCond to headCond printToConsole "Headshot!" ... You can cripple the head only once, yet afterwards it still registers headshots. Doesn't work for the player though. Edited May 28, 2011 by schlangster Link to comment Share on other sites More sharing options...
Recommended Posts