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

I don't know how you would get the ID of the event handler since it's not really a reference that I can create within the SDR.esm.  It's set at run-time without an editor id.  The best you could do is check to see if "sdrPoisonKill" exists, but I don't know if there is a way to do that.

 

Because of how OBSE launches the game, the very first thing that will be loaded is the SDR.dll game settings, before any scripts kick in.

 

All you need to do is provide the listener for the event that I send.  There's nothing more for me to do on my side.  I don't need to detect anything.  I just send out the "sdrPoisonKill" event, and when your listener picks it up along with the arguments, it calls the sub-function.  My event will only be sent if it gets to the end of the poison script, which mimics your scenario, in which you call the on death handler.  so you can just use the exact same function since it would be activated under the exact same circumstances.
 

The only issue is how to prevent the poison script from running in double with mine.  I really don't understand what the issue is with any of my suggestions.  Perhaps I'm not being clear in what I'm suggesting?

 

If this is too much trouble for you, I'll just not run the poison script if Oblvion XP is detected and users won't get an assassination bonus.  Problem solved.

Edited by saebel

Share this post


Link to post
Share on other sites

I understand what you're suggesting, but

GetVariable "iVcheck" SDRQuestID
isn't returning the correct version until much later. The problem is that it's quite feasible for someone to apply a poison as soon as they load their game. In fact, that's exactly what I've been doing. I'll even save a game with a poison applied already and I need the mods ready to process it.

 

You can't do anything because I need to disable Ob XP's poison handling if I detect SDR along with the appropriate handlers. GetFormFromMod returns any object, not just a quest. So I was thinking I could use that to detect your sdrPoisonKill event. Your event sender is a function. I could use that and then use GetName to confirm the event sender has been defined.

 

What's the form ID for your event send function and what's its name? If it doesn't work, then I'm back to telling people to disable Ob XP's poison handling, which won't work because people don't read the documentation. :rolleyes:

Share this post


Link to post
Share on other sites

The event sender isn't a script function.  It's an event handler like any other event handler, but instead of calling one my functions, it just sends a message out into the ether for whatever is listening for it.  In this case the listener that you set up with the code I provided.

 

I think the best idea is to create the SDR version GameSetting.  It will default to 0 on load.  As long is it is at 0, my poison fix script won't run.  When my initialization is done, it will set the game setting with the version number.

 

On your end, you just check that game setting every time you need to apply the poison fix script.  As long as the version is 0, you can safely apply it because my poison fix won't be applied.  You can leave the listener set up as is, because as long as my poison script doesn't run, it also won't send out any messages.

 

The moment my initializer finishes and sets the version number, your script will see it and apply it.

The only real issue is going to be folks who are still using an older version of SDR.  You could use the version checker to capture that (eventually) and pop up a warning and perhaps disable your poison fix script for the duration.
 

Would something like that work for you?

Share this post


Link to post
Share on other sites

With a game setting, I don't think we need to worry about the delay. I'll test it to be sure, but it just seems to be updating the quest variables that's the issue.

 

To make sure I understand: if someone if running SDR with the poison fix code in it, but not a new enough version to have the game setting, then the problem will be with our colliding poison scripts, correct? Which version of SDR had the initial poison script? Perhaps in that case, I just disable Ob XP's poison script and they don't get any points for the kill. Then I can tell them to upgrade. :P

 

Edit: You know, I just thought of an even simpler solution: just change the name of your variable. Instead of iVcheck, change it to iVersion or something. Then we know for sure people have the correct version and we don't need to worry about the previous version being cached. We're still using a version variable, but at least we aren't going through a lot of extra work.

Edited by AndalayBay

Share this post


Link to post
Share on other sites

Actually, never mind. I changed my detection code so that it runs again. I don't do it every time a poison is applied, but in the initialization, I can let it keep repeating. Basically the same as the OBSE check code.

 

No changes needed on your side. Early testing indicates that the new events are working just fine. :D

Share this post


Link to post
Share on other sites

With a game setting, I don't think we need to worry about the delay. I'll test it to be sure, but it just seems to be updating the quest variables that's the issue.

Yes-ish. The game setting will be zero until the initialization process populates it with the version number. But as long as it is zero during the initialization process, none of the rest of my scripts will run, so you should be fine.

 

To make sure I understand: if someone if running SDR with the poison fix code in it, but not a new enough version to have the game setting, then the problem will be with our colliding poison scripts, correct? Which version of SDR had the initial poison script? Perhaps in that case, I just disable Ob XP's poison script and they don't get any points for the kill. Then I can tell them to upgrade. :P

 

Edit: You know, I just thought of an even simpler solution: just change the name of your variable. Instead of iVcheck, change it to iVersion or something. Then we know for sure people have the correct version and we don't need to worry about the previous version being cached. We're still using a version variable, but at least we aren't going through a lot of extra work.

I removed the iVcheck variable entirely and replaced it with the new iSDRsVersion game setting. So if you test for the variable and it exists, then the user has an old version of SDR.

 

Switching over to a game setting is actually much better for my mod, OB XP aside, for similar reasons. Whenever folks upgraded from one version to the next, there would be a brief delay during the initialization phase when the scripts were running for a few seconds when they shouldn't have because it was looking at a quest variable. Using the gamesetting instead should stop that from happening. So solving our SDR-OBXP issue ends up helping SDR in general. :)

 

When it comes to point where you decide whether or not you need to apply the poison fix script, I think all you need to check is:

GetGS iSDRsApplyPoisonFix == 1

GetGS iSDRsVersion >= 8213 (I bumped it up one since it'll be different than the one you have)

 

If both those are true, then you won't need to apply OB XPs poison script fix.

 

It's important that you run it at the time the poison fix would be applied because the user could change the gamesettings via console commands in the middle of the game.

 

Here's the new version: https://www.dropbox.com/s/ipwav63xvphp63w/SDR_Hotfix.zip?dl=0

 

Give it a whirl and let me know how it goes.

Share this post


Link to post
Share on other sites

Actually, never mind. I changed my detection code so that it runs again. I don't do it every time a poison is applied, but in the initialization, I can let it keep repeating. Basically the same as the OBSE check code.

 

No changes needed on your side. Early testing indicates that the new events are working just fine. :D

Too late.   :rofl:

Share this post


Link to post
Share on other sites

Oh well, I tried. :lmao:

 

Early night for me (yes, 2 am is early :lol:), so I'll play with this tomorrow. Hope to be on the forums earlier tomorrow, so I'll switch everything and let you know how it goes.

Share this post


Link to post
Share on other sites

saebel, a couple of things. First, would it be possible to set the version a little earlier, even though SDR hasn't fully initialized? Basically the player could start playing before SDR is completely done and the functions would still work.

 

Second, I don't think our handlers are working all the time. I'm on Skype if you're around.

Share this post


Link to post
Share on other sites

Ok, the scenarios are 1 and 2, usually 1. For scenario 2, your user defined event is triggered and it's calling the special death handler, as expected. For scenario 1, it's just Ob XP's regular death handler that's being triggered. I've run the test four times now and all four times I got the points for killing the wolf, so I'm not sure why I didn't get any points that one time. I haven't been able to replicate it.

 

You might be right about being able to use the regular death handler with your dispatched event. I'll try that next, but it doesn't really matter - it will just save a bit of code.

 

Shall we declare this done?

 

Edit: I didn't get credit for a poison kill again. This time I switched to using Ob XP's regular death handler for the SDR poison kill. The really strange part is that the special death handler wasn't being called anyway - I have some debug statements in the function and they aren't being written to the log. I'll switch back to the special handler and see if the kill is awarded properly. These kills are scenario 1.

Edited by AndalayBay

Share this post


Link to post
Share on other sites

Confirmed. I have to use the custom handler for SDR poison kills, even if SDR doesn't explicitly call it. I won't get credit for the kill otherwise. Here are the log entries:

 

Static log with Ob XP and SDR entries:

 

SDR Version: 0
Supreme Magicka: Initialised Succesfully
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR: v 8.2.1 b3 initialized.  SDR Tweaks.ini file detected and settings applied (if any).
SDR Version: 8213
Lightweight Potions updated values from ini file with weight set to 0.20
SDR: Updated poison applied to weapon.  Original:Burden-Damage Health-Fire Damage (FF005308)  Cloned:Burden-Damage Health-Fire Damage (FF005A78)  Duration:476  Index:3
SDR: Poison killed Timber Wolf! (scenario 1)
SDR: Updated poison applied to weapon.  Original:Burden Potion (000984A5)  Cloned:Burden Potion (FF005A7D)  Duration:120  Index:1
SDR: Poison killed Mud Crab! (scenario 2)
SDR: Updated poison applied to weapon.  Original:Burden-Damage Health-Fire Damage (FF005308)  Cloned:Burden-Damage Health-Fire Damage (FF005A8A)  Duration:476  Index:3
SDR: Poison killed Bandit Bowman! (scenario 3)

 

Ob XP custom log entries:

 

SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 8213
Event
Target Timber Wolf killed by Soren Renard
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 8213
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 0
SDR Version: 8213
Event
Target Mud Crab killed by Soren Renard
Event
Target Bandit Bowman killed by Soren Renard

 

How do you like that for a range of scenarios? :D

 

And I'm pleased to see that all is right with the world. You had me worried that you could be right and we can't have that. Everybody knows women are always right. :yes:

 

So I think we're good to go.

 

Milotek, I'll do more testing about the simultaneous kill. I don't think it would happen with SDR. I'll have to switch to another game instance to test without SDR loaded.

Share this post


Link to post
Share on other sites

Ok, the scenarios are 1 and 2, usually 1. For scenario 2, your user defined event is triggered and it's calling the special death handler, as expected. For scenario 1, it's just Ob XP's regular death handler that's being triggered. I've run the test four times now and all four times I got the points for killing the wolf, so I'm not sure why I didn't get any points that one time. I haven't been able to replicate it.

 

You might be right about being able to use the regular death handler with your dispatched event. I'll try that next, but it doesn't really matter - it will just save a bit of code.

 

Shall we declare this done?

 

Edit: I didn't get credit for a poison kill again. This time I switched to using Ob XP's regular death handler for the SDR poison kill. The really strange part is that the special death handler wasn't being called anyway - I have some debug statements in the function and they aren't being written to the log. I'll switch back to the special handler and see if the kill is awarded properly. These kills are scenario 1.

 

Well it certainly sounds like it's on the right track.  I'd like to see how the code is set up.  I might do some experiments on my side.  Technically any mod could receive the "dispatch" and do something with it.  I have an extra "test" mod for proof of concept trials, collecting frame rates, stuff like that.  I'll set that up with a listener and see what happens.

Share this post


Link to post
Share on other sites

P.S. I am officially confirming that you are correct in how you set up the event listener.   :)

 

I agree that we're good to go.  So I'm going to do a final check on everything, package it, and release it.

 

Also, because of the changes to the sdr.dll, the version gamesetting change, as well as some fixes to the RGO patch, I'm going to release it as 8.2.2.0 and recommend users do a clean install.  This will be the first official non-beta release.

Edited by saebel

Share this post


Link to post
Share on other sites

Yeah, good point. I do reset it when a saved game is reloaded, but there were no reloads during that sequence. I'll take a closer look at my code.

 

Seems to be working though.

Share this post


Link to post
Share on other sites

P.S. I am officially confirming that you are correct in how you set up the event listener.   :)

 

I agree that we're good to go.  So I'm going to do a final check on everything, package it, and release it.

 

Also, because of the changes to the sdr.dll, the version gamesetting change, as well as some fixes to the RGO patch, I'm going to release it as 8.2.2.0 and recommend users do a clean install.  This will be the first official non-beta release.

My previous response was to your previous post. :P Sounds good.

Share this post


Link to post
Share on other sites

New version is up. Download link is in the new testing thread.

 

Early testing indicates that the stacked poison and simultaneous kill issues have been fixed. Also, the new SDR is much faster than before. If you had performance issues when you tried it before, try the new version. :)

Share this post


Link to post
Share on other sites

Wow you two have been busy.  I have been dying over here waiting for you two to finish so I can see the code.  I will download your new version and run all my standard tests.

 

I still have 4 more issues to discuss.  One is super easy to fix.   Two might be impossible to fix.  The last is just something that you might want to know about but everything still works just not like you think. 

 

This last one gave me an idea how to simplify the poison script.  So far it is working.  One strange thing that is happening is in the Finished Block you call the OnDeath handler with the code:

call OBXPfnOnDeath actor, player

But when I use that same line in my new code it doesn't work. It fails the "IF" that gives the XP.   In my code I have to use:

call OBXPfnOnDeath actor, playerRef

In your code, even though you pass it the 'Player' 00000014 the function OBXPfnOnDeath sees it as "PlayerRef" 00000007 so everything works as that is what the "IF" statement wants, "PlayerRef" 00000007.  In my code it when I pass 'Player' 00000014 it sees it as 'Player' 00000014 and fails as the "IF" statement checks against "PlayerRef" 00000007.  I have read that "Player" can sometimes return the same formID as "PlayerRef".  I just find it odd it works in your code and not mine when all I did was copy your code and paste it into a new script.   Makes me think your script is cached or something like that. 

 

The if statement in question is:

if ( killer == playerRef ) || ( companionKill == 1 )

I would either change your code to "PlayerRef" iin the Finished Block or change the "IF" statement to:

if ( killer == playerRef ) || ( killer == player ) || ( companionKill == 1 )

This would make sure it works no matter which one is passed. 

Share this post


Link to post
Share on other sites

My script shouldn't have that problem since I always use PlayerRef. I'm also passing the PlayerRef to OB XPs sdrPoisonKill listener as one of the array items.

 

Even though Player and PlayerRef are technically interchangeable, the cs wiki recommends to always use PlayerRef since it refers to the reference while Player refers to the base object.

 

Here's the article: http://cs.elderscrolls.com/index.php?title=Player

 

Note it details how the Player and PlayerRef have fixed form IDs, even though the PlayerRef can't be found in the Oblivion.esm.

 

Implementing the change isn't too difficult. I opened all scripts and did a search and replace for the following:

"player" with PlayerRef using Whole Word Only, case insensitive

"Player." with "PlayerRef.", case insensitive

"PlayerRefRef" with "PlayerRef", case insensitive

 

I then did a compile all scripts to see if there were errors generated in the console window and cleaned up whatever was left.

Edited by saebel

Share this post


Link to post
Share on other sites

My motto is "if it ain't broke, don't fix it". :P SirFrederik used player in all the scripts and I've never had the need to change them. In many instances, the base object is the one we need anyway.

Share this post


Link to post
Share on other sites

My motto is "if it ain't broke, don't fix it". :P SirFrederik used player in all the scripts and I've never had the need to change them. In many instances, the base object is the one we need anyway.

That assumes that it ain't broke. Maybe there's a tiny leak you have noticed yet. ;)

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  

×