Jump to content

newzilla7

Premium Member
  • Posts

    112
  • Joined

  • Last visited

Posts posted by newzilla7

  1. Another thing you might want to try, since this is a brand new save anyway, is using the SKSE memory manager instead. It doesn't require anything other than editing an ini, so even the creator of SSME recommends using SKSE's manager if you have 1.7+. You can find instructions to set/create the SKSE ini here.

     

    And yes, it is irritating Bethesda limited themselves to unhandled exceptions. It would have been nice for them to, anticipating the modding scene, actually create a usable bug logger for crashes not caused by scripting. However, they did design the entirety of an open-world 200+ hour roleplaying game, so I'll give them the benefit of the doubt :laugh:

  2. I went through and cleaned up the code, removing unnecessary events, reorganizing the remaining events, functions, and variables, and adding comments. I also added a toggle for the debug messages, and an event to clear the variables when the effect ends (aka when the shield is lowered) so no junk is left over, just in case Skyrim gets wonky with its scripting (read: when it does).

     

     

     

    Scriptname AbPerfectBlockingEffectScript extends ActiveMagicEffect
    
    {removes all incoming damage under certain conditions}
    
    
    
    Keyword Property ShieldKey auto        ; Keyword for ArmorShield; used to determine if item is actually a shield or just a weapon
    
    float savedHealthMax        ; holds maximum health to determine what 100% health actually means
    
    float savedHealthPercentage        ; holds percentage of health before a blocked attack to determine how much to restore
    
    bool DEBUG_MESSAGES = true        ; change to false to disable debug messages
    
    
    
    Event OnEffectStart(Actor akTarget, Actor akCaster)        ; effect starts when blocking commences
    
        if DEBUG_MESSAGES
    
            debug.messagebox("Effect started, setting health...")
    
        endif
    
        
    
        savedHealthPercentage = akCaster.GetAV("Health")
    
        savedHealthMax = akCaster.GetAV("Health") / savedHealthPercentage
    
    EndEvent
    
    
    
    Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)        ; intercepts hit and determines whether to remove damage or not
    
    
    
        if abHitBlocked
    
            if DEBUG_MESSAGES
    
                debug.messagebox("Hit, but blocked. Activating Perfect Blocking...")
    
            endif
    
            
    
            ActivatePerfectBlocking()
    
        else
    
            savedHealthPercentage = GetCasterActor().GetAVPercentage("Health")
    
            
    
            if DEBUG_MESSAGES
    
                debug.messagebox("Hit and not blocked! Resetting health...")
    
                debug.messagebox("New health percentage is " + savedHealthPercentage + ", or " + savedHealthPercentage * savedHealthMax)
    
            endif
    
        endif
    
        
    
    EndEvent
    
    
    
    Event OnEffectFinish(Actor akTarget, Actor akCaster)        ; effect finishes when shield or weapon is lowered; values are reset to ensure no accidental carryover to a new blocking session
    
        if DEBUG_MESSAGES
    
            debug.messagebox("Effect finished, resetting variables...")
    
        endif
    
        
    
        savedHealthPercentage = 0.0
    
        savedHealthMax = 0.0
    
    EndEvent
    
    
    
    Function ActivatePerfectBlocking()        ; called when all conditions for damage-removed blocking are met
    
        if DEBUG_MESSAGES
    
            debug.messagebox("Resetting health!")
    
            debug.messagebox("Saved max is " + savedHealthMax + ", saved percentage is " + savedHealthPercentage)
    
        endif
    
        
    
        float percentageDifference = savedHealthPercentage - GetCasterActor().GetAVPercentage("Health")        ; should resolve like so: earlier health percent was 90%, health percent after damage (now) is 84%, difference is 6%
    
        float amountToRestore = percentageDifference * savedHealthMax        ; should resolve like so: 6% (or 0.06) of maximum health should equal the lost health points
    
        
    
        if DEBUG_MESSAGES
    
            debug.messagebox("Percent difference is (" + savedHealthPercentage + " - " + GetCasterActor().GetAVPercentage("Health") + " = " + percentageDifference + ")")
    
            debug.messagebox("Amount to restore is (" + percentageDifference + " * " + savedHealthMax + " = " + amountToRestore + ")")
    
        endif
    
        
    
        GetCasterActor().RestoreAV("Health", amountToRestore)        ; add the determined health points back to health
    
        
    
        if DEBUG_MESSAGES
    
            debug.messagebox("New health is " + GetCasterActor().GetAV("Health"))
    
        endif
    
    EndFunction
    

     

     

  3. First, run bashed patch. Make sure when you build the patch it's just above ASIS-Dependancy.esp, and deactivate ASIS-Dependancy. You want the bashed patch run beforehand, so PerMa and ASIS can use it for their patches.

    Then, download and install SUM, the Skyproccer Unified Manager. Go to the SUM reproccer folder and run SUM.jar. It will automatically detect and run both reproccers, making sure they're compatible with each other.

    I hope that helps! Please reply if I haven't explained anything well.

     

    EDIT: I fixed a mistake I made regarding the bashed patch order.

  4. This mod is in answer to the request found here.

     

    I've put together a script to intercept and reverse damage done while blocking under certain conditions. It is attached to the player and any humanoid NPC through a racial effect.

     

    I've kept many debugging messages to ensure the mod works properly as I add new functionality.

     

    Here is the script:

    Scriptname AbPerfectBlockingEffectScript extends ActiveMagicEffect
    {removes all incoming damage under certain conditions}
    
    Keyword Property ShieldKey auto
    float savedHealthMax
    float savedHealthPercentage
    
    Function ActivatePerfectBlocking()
    	debug.messagebox("Resetting health!")
    	debug.messagebox("Saved max is " + savedHealthMax + ", saved percentage is " + savedHealthPercentage)
    	
    	float percentageDifference = savedHealthPercentage - GetCasterActor().GetAVPercentage("Health")
    	debug.messagebox("Percent difference is (" + savedHealthPercentage + " - " + GetCasterActor().GetAVPercentage("Health") + " = " + percentageDifference + ")")
    	float amountToRestore = percentageDifference * savedHealthMax
    	debug.messagebox("Amount to restore is (" + percentageDifference + " * " + savedHealthMax + " = " + amountToRestore + ")")
    	
    	GetCasterActor().RestoreAV("Health", amountToRestore)
    	debug.messagebox("New health is " + GetCasterActor().GetAV("Health"))
    EndFunction
    
    Event OnInit()
    	debug.notification("Perfect Blocking script initialized.")
    EndEvent
    
    Event OnEffectStart(Actor akTarget, Actor akCaster)
    	debug.notification("Effect started, setting health")
    	savedHealthPercentage = akCaster.GetAV("Health")
    	savedHealthMax = akCaster.GetAV("Health") / savedHealthPercentage
    EndEvent
    
    Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
    	debug.notification("Object equipped, setting health")
    	savedHealthPercentage = GetCasterActor().GetAV("Health")
    	savedHealthMax = (GetCasterActor().GetAV("Health") / savedHealthPercentage) * 100
    EndEvent
    
    Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    
    	if abHitBlocked
    		debug.messagebox("Hit, but blocked. Activating Perfect Blocking...")
    		ActivatePerfectBlocking()
    	else
    		debug.messagebox("Hit and not blocked! Resetting health...")
    		savedHealthPercentage = GetCasterActor().GetAVPercentage("Health")
    		debug.messagebox("New health percentage is " + savedHealthPercentage + ", or " + savedHealthPercentage * savedHealthMax)
    	endif
    	
    EndEvent

    I recognize the OnInit function is not safe, and I will remove it when I'm done testing.

  5. Woohoo! I got something working!

     

    Basically, when you start blocking the script saves your health. Whenever you take damage while blocking, as long as you meet the conditions (none at this point), your health is returned to the saved value. Unfortunately, Bethesda neglected to make it easy to access the needed values, so I had to create a somewhat convoluted system that tracks your max health and current percentage of that.

     

    Here's the code, if anyone's interested.

    Scriptname AbPerfectBlockingEffectScript extends ActiveMagicEffect
    {removes all incoming damage under certain conditions}
    
    Keyword Property ShieldKey auto
    float savedHealthMax
    float savedHealthPercentage
    
    Function ActivatePerfectBlocking()
    	debug.messagebox("Resetting health!")
    	debug.messagebox("Saved max is " + savedHealthMax + ", saved percentage is " + savedHealthPercentage)
    	
    	float percentageDifference = savedHealthPercentage - GetCasterActor().GetAVPercentage("Health")
    	debug.messagebox("Percent difference is (" + savedHealthPercentage + " - " + GetCasterActor().GetAVPercentage("Health") + " = " + percentageDifference + ")")
    	float amountToRestore = percentageDifference * savedHealthMax
    	debug.messagebox("Amount to restore is (" + percentageDifference + " * " + savedHealthMax + " = " + amountToRestore + ")")
    	
    	GetCasterActor().RestoreAV("Health", amountToRestore)
    	debug.messagebox("New health is " + GetCasterActor().GetAV("Health"))
    EndFunction
    
    Event OnInit()
    	debug.notification("Perfect Blocking script initialized.")
    EndEvent
    
    Event OnEffectStart(Actor akTarget, Actor akCaster)
    	debug.notification("Effect started, setting health")
    	savedHealthPercentage = akCaster.GetAV("Health")
    	savedHealthMax = akCaster.GetAV("Health") / savedHealthPercentage
    EndEvent
    
    Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
    	debug.notification("Object equipped, setting health")
    	savedHealthPercentage = GetCasterActor().GetAV("Health")
    	savedHealthMax = (GetCasterActor().GetAV("Health") / savedHealthPercentage) * 100
    EndEvent
    
    Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    
    	if abHitBlocked
    		debug.messagebox("Hit, but blocked. Activating Perfect Blocking...")
    		ActivatePerfectBlocking()
    	else
    		debug.messagebox("Hit and not blocked! Resetting health...")
    		savedHealthPercentage = GetCasterActor().GetAVPercentage("Health")
    		debug.messagebox("New health percentage is " + savedHealthPercentage + ", or " + savedHealthPercentage * savedHealthMax)
    	endif
    	
    EndEvent
    

    Next up I'll be implementing some of the conditions we need.

  6. I found that it would be a grueling task to add the perk to every actor, as you cannot add perks dynamically. Instead, the effect right now is a constant spell/script that undoes any damage taken while blocking correctly. This isn't quite perfect, as the damage is still applied, but it does still allow for staggering, which is realistic, I guess. If someone knows a script function to replicate ModIncomingDamage, by all means let me know.
  7. Thanks, BigBizkit. I thought GetRelativeAngle wouldn't work correctly with perks, but if it will, I much prefer that. I want to learn Papyrus, but I'd rather not actually try making a mod while doing that ;)

  8. One thing that should be noted here is the fact that you NEVER want to remove mods during a play through. It will almost always break your saves, sometimes to the point that you will have to start over.

     

    I also don't agree with what newzilla is saying when he says " 1) install mods in whatever order you want " . You still will need to use LOOT, Wrye Bash, and TES5Edit to make sure there are no load problems, missing masters, or incompatibilities.

    Yes, of course! I meant to say that the installation order doesn't matter, while the load order is important.

     

    And thank you for clarifying on removing mods, I should have mentioned that :/

  9. Thanks :)

     

    Mod Organizer handles the installation of mods by keeping them in their own separate folders. This means that one mod never overwrites another mod, or any piece of the vanilla game. When Skyrim is started through Mod Organizer, the tool constructs a virtual Data folder for Skyrim to access, which is created based on the priorities you set in Mod Organizer.

     

    For example, a mod called Werechair replaced the model for the werewolf with a chair. If loaded it in Mod Organizer, this mod would not actually change any files. Instead, if activated, it would be chosen for the virtual Data folder instead of the default mesh. This means that I can make whatever changes I want to my game, but if I don't like the mod, I deactivate it. Since the real Data folder was never changed, it's like the mod wasn't there in the first place.

     

    This not only allows you to test mods with less chance of breaking your game, but also lets you install your mods in any order you wish. Because of the way assets are dynamically added, you can much more easily fine-tune which mods change what.

     

    It gets a little bit more complicated than that, but the main benefit for you is the ability to 1) install mods in whatever order you want, and 2) remove many incompatibilities created by the way most modding tools handle mod assets.

  10. The list you're using doesn't have any incompatibilities pop out at me immediately. Were there specific mods you were having trouble with? If you couldn't identify the mods, what problems were you experiencing in general?

     

    One thing I highly recommend when you have a large number of mods (>10-15) is to invest the time necessary to use Mod Organizer. In fact, while Workshop mods are harder to set up, using Mod Organizer can make them just as compatible as Nexus alternatives. If you're interested in setting that up, I'll do what I can to make Mod Organizer a bit less confusing for you.

  11. I may have found a better solution that would allow realistic blocking. If I use active magic effects on all humanoid actors to create the effect, not only can I correctly access GetRelativeAngle, I can much more easily place riders for race, weapon, etc. and fine-tune the effects of different weapons, e.g. torch blocks swords but not dragonfire.

     

    When I have some time today and tomorrow I'll try this out.

  12. The big issue I can see is the organization of your main masters and Unofficial Patches. I don't know why LOOT does this sometimes, but they should not be separate. Here is the optimized load order:

    • Skyrim.esm
    • Update.esm
    • Unofficial Skyrim Patch.esp
    • Dawnguard.esm
    • Unofficial Dawnguard Patch.esp
    • Hearthfires.esm
    • Unofficial Hearthfire Patch.esp
    • Dragonborn.esm
    • Unofficial Dragonborn Patch.esp
    • -other masters-
    • HighResTexturePack01.esp
    • HighResTexturePack02.esp
    • HighResTexturePack03.esp
    • Unofficial High Resolution Patch.esp

    Reorganize that and see if it helps.

  13. Sorry for the lack of updates, I've been busy with work :)

     

    Darkfoot, unfortunately I'm lost on the directional blocking. However, I can take into account your other suggestions. I'll keep you guys posted on my progress.

  14. Thanks for the detailed description! I was having trouble finding the correct riders. Maybe next time there's a request I'll be able to get my act together and actually make the mod in a timely manner ;)
  15. Though AMDs have higher clock speeds, Intels consistently perform better in game processing. I would recommend looking at some benchmarks of AMD vs Intel for Skyrim and seeing if the performance gain is worth it for you. If it's any help, I went with an Intel i7 and it's never let me down. It runs Skyrim crazy well.

×
×
  • Create New...