Jump to content
  • Announcements

    • AndalayBay

      Orphan Attachments   07/31/2018

      I have been doing some housekeeping lately and I've noticed that I had a lot of orphaned attachments. Attachments get orphaned when the PM or post is deleted without removing the attachment first. Deleting a PM or post does not delete the attachment and the file or image remain on the server. I'd like to ask all members to go through their attachments and delete any attachments you don't need anymore or those that have been orphaned. Where can I get a list of my attachments? Click on your display name in the upper right corner of the forums and pick "My Attachments" from the drop-down list. How can I tell an attachment is orphaned? If the PM has been deleted, you'll see a message like this in your attachment list: Unfortunately there is no message if the post has been deleted, so please check your old posts. We do purge old birthday threads every once in a while. Also some hosted projects have been shut down, so you may have orphaned attachments on one of those locations. Thanks!
Sign in to follow this  
Milotek

Poison Kill Script Discussion

Recommended Posts

AndalayBay, remember the Finished Block doesn't care about the type of poison that made the kill.  It will give credit for any poison as long as it meets the other conditions.  But yes the stacked poison is working.  The Simultaneous Kill I explained page one still exists.

 

Here is a quote from the post:

In a nutshell, if you have an enemy that is one one conventional weapon blow from death and poison your weapon for the final blow. you will get two OPXP kill messages along with the associated XP.  The easiest way to test this is to find a creature, such as a mud crab, that you can kill in one conventional weapon strike and poison the weapon and strike the creature. 

 

 

But I do have a fix for it.  That is what we were discussing before you found out things weren't working for you.  Also the first log I posted showed that issue.  Nothing that you post to the Conscribe log shows it though. 

Edited by Milotek

Share this post


Link to post
Share on other sites

Ok, so check this out.  Here's the documentation:

 

 

User-Defined Events

 

In addition to the events supplied by OBSE, mods can also register event handlers for events dispatched by other mods. These types of events are referred to as "user-defined events". The event handler for a user-defined event always takes one argument: a Stringmap. The stringmap argument always includes the following two key-value pairs:

 

"eventName": a string indicating the event which occurred

"eventSender": a string indicating the origin of the event. By default this is the filename of the mod which dispatched the event, unless that mod supplied an alternate sender name.

The stringmap argument will also contain any additional data supplied by the sender of the event.

To register an event handler for a user-defined event, use SetEventHandler. To dispatch an event to any registered listeners, use DispatchEvent

Example:

 

scriptname EventHandler

array_var args

begin Function {args}

print "Event " + args->eventName + " received from " + args->eventSender

print $arg->activator + " was activated by " + $arg->activatedBy

end

 

scriptname EventSender

begin onActivate

DispatchEvent "Activated" (ar_Map "activator"::GetSelf "activatedBy"::GetActionRef)

end

DispatchEvent - dispatches a user-defined event to any registered listeners. The eventName parameter specifies the event that occurred; this should be fairly unique to prevent event name clashes between different mods, but the event handler can also disambiguate name clashes by checking the name of the event sender if necessary. The optional second parameter is a StringMap containing any additional information about the event. When the event is dispatched, the array will also include the event name and the name of the sender. If omitted, the name of the sender is the filename from which the event originated; otherwise it matches the supplied third argument.

(dispatched:bool) DispatchEvent eventName:string args:StringMap senderName:string

 

 

 

I think what you need to do is add the following line of code in your initialization set up:

SetEventHandler "sdrPoisonKill" OBXPfnOnDeath
Then what I do at the end of my poison effect script is the following:

begin ScriptEffectFinish

    let sdrQ.rPoisonCloned := 0

; the resistances of certain creatures isn't captured properly, so they die in between the update cycles
; try to capture those cases here - return in update cycle not working.  Also need to account for critter
; dying by brute force, in which case the kill will be registered by the regular kill script.

    if iKillRegistered
        return
    endif

    if rActor.GetDead
        if rActor.IsCreature
            if ( GetPCMiscStat 5 == fKillsCreatures )
                ModPCMiscStat 5 1
                if iDebug
                    PrintToConsole "SDR: Poison killed %n! (scenario 2)" rActor
                endif
                DispatchEvent "sdrPoisonKill" (ar_Map "target"::rActor "killer"::PlayerRef)
;               check for assassination skill up directly, because OnDeath handler probably missed it
                if PlayerRef.isSneaking
                    Call sdrEHAssassinationCheck rActor PlayerRef 1
                endif
            endif
        else
            if ( GetPCMiscStat 6 == fKillsNPCs )
                ModPCMiscStat 6 1
                if iDebug
                    PrintToConsole "SDR: Poison killed %n! (scenario 3)" rActor
                endif
                DispatchEvent "sdrPoisonKill" (ar_Map "target"::rActor "killer"::PlayerRef)
;               check for assassination skill up directly, because OnDeath handler probably missed it
                if PlayerRef.isSneaking
                    Call sdrEHAssassinationCheck rActor PlayerRef 1
                endif
            endif
        endif

    endif

end
Note the two "DispatchEvent" lines.

 

In theory what this will do is that whenever I dispatch the "sdrPoisonKill" event, your "sdrPoisonKill" event handler will pick it up along with the arguments I've passed and then activate your on death handler with those arguments, causing the OB XP kill points to be added. After the OB XP kill points are added, then my assassination script will kick in if appropriate.

 

So in theory, your initialization code would be wrapped in something along the following lines:

if GetModLoaded "SDR.esm"
  ; code to check version compatibility (will be 8212 +)
  if versionokay == 1
    ; code to check that SDR's poison script is active
    if GetGameSetting iSDRsApplyPoisonBugFix == 1
      ; code to disable your poison fix
      let OBXPoisonFix := 0
      ; code to set up your event listener
      SetEventHandler "sdrPoisonKill" OBXPfnOnDeath
    endif
    ; whatever other SDR compatibility stuff needs to be here
    ; (stuff for disabling sneak multiplier if SDR assassination skill up is active)
  endif
endif
If this works, that would be freaking badass. What's more, it means that in theory you could set this up to listen for and call ANY function from another mod, not just the default handlers. In this particular case, it just happens to be the same function because that's what is needed for the xp.

 

Wanna try it?

 

 

Absolutely. That looks awesome. Ok, I'll use sdrPoisonKill as the event name. Once you get that set up, we'll give this a go. It'll be later this evening though - it's 5 pm here and I'll be heading off for dinner soon. We can link up later (around 9 pm my time, I'd say) and even get on Skype if needed.

 

Milotek, the problem with SDR was making the issue worse, but there was a bug in the scripts that I fixed. In terms of the simultaneous kill, I'll have to see if I can recreate it. I'll have to add some debug statements to get the issue logged.

Share this post


Link to post
Share on other sites

No it's not - I've tried it. :D I just get the poison kill or just a regular kill. I think you need to find a critter that's just the right level. I'll try it with a mud-crab like you suggest, but I suspect it will die from the sword hit and the poison won't matter. We'll see.

Share this post


Link to post
Share on other sites

Sounds good on the timing. I still have some other stuff I'm working on on the .dll side, and it's going to take me awhile. I'll pop in the code real quick so it will be ready to go.

 

What's your version number going to be so that I can check for it?

 

P.S. The other neat thing about the dispatch is that I don't have to check for Oblivion XP. I just put it out there, and any mod that is listening for it can do something with it. :)

Edited by saebel

Share this post


Link to post
Share on other sites

I have been wanting to try user-defined event.  I may do some testing to see if I can get them to work in general.  Good luck sorting things out. 

Share this post


Link to post
Share on other sites

No it's not - I've tried it. :D I just get the poison kill or just a regular kill. I think you need to find a critter that's just the right level. I'll try it with a mud-crab like you suggest, but I suspect it will die from the sword hit and the poison won't matter. We'll see.

Actually there are multiple ways to make it happen but the way I described it was just the easiest. 

Share this post


Link to post
Share on other sites

I think it's time to bump it up to 3.4.2, so 342. Yours is going to be 8212, right?

Yep.

 

I'm setting it up so that if SDR detects the version variable to be either non-existent or less than 342 it will automatically disable SDR's poison fix script for backwards compatibility in case they don't get around to updating Oblivion XP.

Edited by saebel

Share this post


Link to post
Share on other sites

Technically, I posted a link to the right file. But I'll bet you Dropbox didn't update it properly. Sometimes it does that when it thinks there haven't been any changes.

 

Edit: To be more specific, I replaced the file inside the zip file. I think my system didn't change the date or the file size, so dropbox thought there weren't any changes and so didn't sync it. :(

 

This should work: https://www.dropbox.com/s/3ahiti7es3zucdc/SDR_8212_hotfix.zip?dl=0

Edited by saebel

Share this post


Link to post
Share on other sites

I really hate Oblivion scripting sometimes. :mad: I'm having problems with detecting the version of SDR. I can detect SDR just fine, but the version is still retrieving 8209 sometimes. I have moved the detection code so that it's later  in the script, but it still returns 8209. I know you suggested using a timer so that it waits 10 seconds and I'm sure that would work, but I'm afraid players won't wait that long. They will load their games and expect to have everything ready to go. I don't know what to do. Ideas?

Share this post


Link to post
Share on other sites

I really hate Oblivion scripting sometimes. :mad: I'm having problems with detecting the version of SDR. I can detect SDR just fine, but the version is still retrieving 8209 sometimes. I have moved the detection code so that it's later  in the script, but it still returns 8209. I know you suggested using a timer so that it waits 10 seconds and I'm sure that would work, but I'm afraid players won't wait that long. They will load their games and expect to have everything ready to go. I don't know what to do. Ideas?

I hear ya!!!

 

Well, I think you pretty much have only two options:

1. store the version number during initialization.

- side effect is that it will most likely grab the wrong one if they are transitioning between SDR versions. Once the transition is complete and the game is saved, the next time OB XP launches, it will see the new SDR version and update the local variable. But until that happens, it will return the wrong version and weird things will happen.

2. Run the version check each time you do a poison fix check.

- There is a wee bit more overhead there since it will run every time a poison is added. But then, I don't think that sort of thing will happen too often. But unless they apply a poison within the first 10 seconds when transitioning between SDR versions, you should be okay.

Share this post


Link to post
Share on other sites

 

I really hate Oblivion scripting sometimes. :mad: I'm having problems with detecting the version of SDR. I can detect SDR just fine, but the version is still retrieving 8209 sometimes. I have moved the detection code so that it's later  in the script, but it still returns 8209. I know you suggested using a timer so that it waits 10 seconds and I'm sure that would work, but I'm afraid players won't wait that long. They will load their games and expect to have everything ready to go. I don't know what to do. Ideas?

I hear ya!!!

 

Well, I think you pretty much have only two options:

1. store the version number during initialization.

- side effect is that it will most likely grab the wrong one if they are transitioning between SDR versions. Once the transition is complete and the game is saved, the next time OB XP launches, it will see the new SDR version and update the local variable. But until that happens, it will return the wrong version and weird things will happen.

2. Run the version check each time you do a poison fix check.

- There is a wee bit more overhead there since it will run every time a poison is added. But then, I don't think that sort of thing will happen too often. But unless they apply a poison within the first 10 seconds when transitioning between SDR versions, you should be okay.

 

 

The script has no problem detecting SDR, it's just detecting the version number properly that's the issue. Perhaps I do the SDR check and repeat the version check somehow if it's detected. Going to bed now, but I'll sleep on it. :P

Share this post


Link to post
Share on other sites

saebel, would it be good enough to just check for  iSDRsApplyPoisonBugFix being 1? The code is detecting SDR just fine, but it's not returning the right value for the version. The version check is somewhat artificial anyway - it would be better to just check for the variables we need. Now I'm guessing that your ApplyPoisonBugFix variable has been around for a while, so testing for that isn't good enough. Is there any way to test for the sdrPoisonKill event?

 

Also, where did you get that documentation from?

 

Edit: I notice that setEventHandler returns a boolean indicating success or failure. I could try using that, but I suspect it only evaluates whether my function exists, not the event itself.

Edited by AndalayBay

Share this post


Link to post
Share on other sites

saebel, would it be good enough to just check for  iSDRsApplyPoisonBugFix being 1? The code is detecting SDR just fine, but it's not returning the right value for the version. The version check is somewhat artificial anyway - it would be better to just check for the variables we need. Now I'm guessing that your ApplyPoisonBugFix variable has been around for a while, so testing for that isn't good enough. Is there any way to test for the sdrPoisonKill event?

 

Also, where did you get that documentation from?

 

Edit: I notice that setEventHandler returns a boolean indicating success or failure. I could try using that, but I suspect it only evaluates whether my function exists, not the event itself.

Docs come from OBSE v21 download. The OBSE website only has docs for v20.

 

Testing for iSDRsApplyPoisonBugFix should be fine. Since it's a game setting, if the game setting doesn't exist (for earlier versions of SDR) or is set to 0, it won't return a 1. In which case yours would kick in. In fact, because it's a game setting, you don't even need to test for SDR. :)

 

I think the boolean return on the SetEventHandler call is whether or not the handler was successfully set.

Share this post


Link to post
Share on other sites

But earlier versions of SDR had that game setting, didn't they? So just because it's set to 1 doesn't mean the events exist. The ideal solution would be to test if SDR has those user events defined.

Share this post


Link to post
Share on other sites

only way to do that is through version number checking. It should work. Not sure why it wouldn't.

 

Again, I think the best way to do it is to run the check before the poison script check does anything.

 

; first detects if poison is applied.
; if so does the following

let skipFix := 0
if poisonfixSDR == 1
    let sdrversioncheck := call sdrVersionCheckFunction
    if sdrversioncheck == 8212
        let skipFix := 1
    endif
endif
  
If poison fix == 1 && skipfix != 1
 ; do stuff
endif

Share this post


Link to post
Share on other sites

I know how to write the code, C. :P It's always better to check for the existence of a function or class rather than checking version numbers. User defined events include an eventName and eventSender, so I could check those, but they are a little late. I'll continue poking about.

Share this post


Link to post
Share on other sites

Checking the events won't help until they are actually sent I think.  You need to be able to know if the feature is active/running before yours fires.  I honestly can't think of any method to do this other than checking SDR's version number if you don't want to apply a poison fix.

 

The only other possible solution I can come up with is to create a custom game setting specifically for SDR's version number (one for the plug-in and another for the esm).  By default, the SDR.esm gamesetting would be 0, and then set by the initializer.  So whenever your scripts decide to run a poison script check, if they detect iSDRsApplyPoisonFix == 1 and iSDRsVersion >= 8218 then it won't apply the fix, otherwise it will.

 

On my side, I could do something similar.  As long as the iSDRsVersion number is 0, that means SDR hasn't initialized yet, and so none of my scripts will run until it detects a version number, implying that all the rest of the game settings, defaults, sub-scripts, arrays, etc. have been populated.

 

There will still be a slight hiccup when folks update to my new version since the old scripts will still be in memory, but once that is passed, it should work fine moving forward.

 

Would that help?

 

(It's actually something I might do anyway, because it helps stop things from happening until after SDR initializes completely, which is a good thing in my book, considering how complicated and fragile SDR is)

Edited by saebel

Share this post


Link to post
Share on other sites

From what I've found, if we could check for events or functions, we'd be fine. The initialization seems to happen in phases. In the first phase, the mod is registered and the quests. The code detects SDR just fine. It also finds your quest snd detects the variable. As you've discovered, though, the variable isn't updated until much later.

 

I'm already checking if a quest exists. Perhaps I just need to check for the form ID of you event handler. That's my thought. I really don't want to make this too complicated.

 

On my side, what do you really need to know? I think you need to know that I've got a function that will handle your custom event. I can't use Oblivion XP's regular onDeath handler. That gets called by the default onDeath event which has different parameters, so I need to create a new one. Once I've set it up, I can give you the form ID. So perhaps that's how you can handle it on your side. That way, we don't have to worry about updating the version number each time we do a new release, which I can see me forgetting. :P

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×