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!

saebel

Members
  • Content count

    66
  • Joined

  • Last visited

About saebel

  • Rank
    Cave Bear

Profile Information

  • Gender
    Not Telling
  1. I have tried many different ways of calling the functions, and it has failed to compile every time. I've tried resolving the errors by including various additional dependencies, and it just ended up causing more errors. I really need someone who knows what they are doing to look at my code. This is beyond my skill set. And I also don't have time to try and wrestle with it anymore. If no one can, it's fine, because the scripted solutions work. It's just a shame that I can't overcome this one small limitation.
  2. NVIDIA GTX 1080 does not like OBSE

    I still usually have Wrye Bash running at the same time because I'm constantly making changes and updating my installer package. But yes, I don't *need* to launch the game or CSE through Wrye Bash's links. It just became a habit. But now that I have identified the lag being caused by using WB's shortcuts, I've hidden those shortcuts from Wrye Bash so I don't accidentally click on them. I just use other shortcuts that I've created and added to my Windows toolbar. Problem solved... for now.
  3. NVIDIA GTX 1080 does not like OBSE

    Okay, so this is interesting: I used the Display Driver Uninstaller (already had it) Reinstalled latest drivers, skipping GeForce Experience (which I'm fine with - never liked it much) Rebooted computer Normally, at this point, what I've been doing is launching Wrye Bash, and then launching the game or CSE. This time, however, I was impatient and wanted to get right to it, so I launched the CSE directly... no lag, no problem. Same with the obse loader. Then I launched Wrye Bash. Launched CSE from within WB - and the lag came back! So WB was the culprit. Not sure *why* that would be the case when you consider that all things being the same, the only change was the graphics card. I'm running WB 307.201712232300. Anyway, I can live with that. I just won't use WB to launch CSE or the game. Thanks for the tips and advice.
  4. NVIDIA GTX 1080 does not like OBSE

    I uninstalled the drivers and experience using a clean install program, and that definitely got rid of the problem. Question is whether I can find the right driver moving forward.
  5. NVIDIA GTX 1080 does not like OBSE

    Well, the game itself runs fine. And CSE works too after it's loaded. It's just the 45 second delay that's bugging me. (Actually timed it, so that's not an exaggeration). I also tried doing a clean install of OBSE and CSE, hoping that would solve the problem. It didn't. There's no doubt it's gotta be the new GTX 1080. According to the website, it works with Direct X 11 and 12. It doesn't mention earlier versions at all, but that doesn't necessarily mean it's not compatible. Need to do more research.
  6. Just installed a new graphics card, and I'm getting some super weird behavior that I think is linked to OBSE. It's an Nvidia GTX 1080. Whenever I launch the CSE or Oblivion via OBSE, there is this crazy long lag while one or the other loads. It feels like anywhere from 10-30 seconds (haven't timed it). I can't switch over to any other apps. And if I move my mouse, it moves like molasses and it goes in weird directions that I can't control - as if a ghost had taken it over. Once CSE or Oblivion finally loads, everything goes back to normal. But it's insanely frustrating!! Anyone have any ideas?
  7. Unfortunately, I haven't been able to figure out how to tap into the ArrayVarMap data. It's not the same class/structure as the OBSEArrayInterface. That same section has the code for removing elements from an array, assuming I know the array ID.
  8. Actually, I take it back. I think you may be on to something with the "AssignCommandResult". I messed around with it a little bit in a new command function that either retrieves or creates a new array for the master array. I was able to extract the array ID from the "result" portion before the command ended. So that's good news. My concern though is whether it will work in a nested function, and will that mess something else up in the greater scheme of things?
  9. Yup. That's all part of the overall problem. Getting the initial master array ID is not a problem. It's when your start digging down into the nested arrays. Also, I took a look at the plugin example that returned the array ID. What it's doing is using a console print of the result, which is an Oblivion function. And unfortunately, the function is not exposed. It is basically the exact same technique I am using in my script to get the array ID in the first place. But it doesn't actually return the array ID within the .dll in any usable form, because it's a "void" function. So I can't even convert it into a string within the .dll. Seriously - why the hell is this so f'ing hard. Yeesh.
  10. One possible idea that may be the next best thing to ar_Erase is to create a "cloned array", but skip cloning the key/value pairs that are supposed to be dropped, and then replace the original array with the cloned array. The original array will no longer be referenced, so OBSE will remove it when it handles it's garbage collection routines. So for example, let's say I have StringMap1 with three key/value pairs ([modA:data],[modB:data],[modC:data]). I then create a new OBSE StringMap1clone. I create a loop that cycles through StringMap1. It grabs the key of each value pair, and tests to see if the mod is in the active load order. If it is, it copies the key/value pair over to the clone. If it isn't, then it is skipped. In this example, let's assume ModB is no longer active. When the loop finishes, the clone would only have the ModA and ModC key/value pairs. The original array would then be replaced by the clone. Something like that should be able to work for the lower tier items when removing invalid/deleted refs, data groups, or specific data keys from the data sets. I'm not sure about replacing the master array though. That could be problematic. But it occurs to me that the array ID of the master array is stored in a game setting global. So potentially I could swap out that ID with the new one created by the clone (which should be capturable). I might also be able to use that ID to tap into the EraseElements function. I haven't tried that yet though.
  11. I appreciate the examples and ideas, but I don't see how the script slices can help. Part of that is because although I understand the purpose of keys and how they are used for creating data bases and relationships (I make a living working with FileMaker), I don't really understand what you are doing with the scripts in terms of how I can apply the techniques to my problem of removing a key/value pair within the .dll. I already solved the problem of using formIDs as index keys with a GetBaseRef function that strips the mod index from the Ref ld and storing the base RefIds in a child numerical map of their parent mod. So load order becomes irrelevant. As I mentioned before, I already have scripted solutions that work. I just want to port those into the .dll to boost performance, but there is no method I can find that allows me to tap into the equivalent of ar_Erase. I don't want to have to create an entire set of arrays to track the IDs of the arrays created. It's cumbersome and problematic. The array ID data *is* already there and being tracked by OBSE. I just can't figure out how to get to it using OBSE's internal .dll structures, classes, and methods. I'm not clear about the difference between COMMAND_ARGS and PASS_COMMAND_ARGS beyond that they are structures that are created from predefined information as well as parameters that are passed when an OBSE function is called from a script. You have to evaluate it in order to extract the passed parameters and get things like the script object that sent the command, the calling ref (if any), etc., so that you can process it and return a result. It's a little murky.
  12. That's an interesting idea. But I don't need the IDs when the arrays are created. I need them later, when I want to delete an key/value pair from the array, and by that point, they are long gone. I suppose I could create some form of massive reference array that stored all the array IDs that were created and the context under which they were created. But I fear that would be just as cumbersome and complex as the nested arrays are. Assuming that worked, and I was able to use the reference table to find the ID and use that to remove the reference, I would still have to address the issue of removing key/value pairs from the reference table... which I would have to get/store the ID of. And then I am back to the scripted functions again. I think ultimately that would end up adding even more overhead to the problem without really improving on the current solution I have at the moment.
  13. The COMMAND_ARGS are passed via the scripted function per the OBSE documentation: ar_Erase - erases elements from an array. You may provide a single element, in which case only that element will be erased and only if it is present. Or, you may provide a range in slice notation. Any elements greater than or equal to the lower bound and less than or equal to the upper bound of the range will be erased. If the array is of type Array, elements above the erased elements will be shifted down. Returns the number of elements removed. Users of OBSE 0020 or later may omit the second argument; doing so will erase all elements of the array. (numRemoved:int) ar_Erase target:array index:arrayIndex (numRemoved:int) ar_Erase target:array range:slice (numRemoved:int) ar_Erase target:array Examples: array_var arr let arr := ar_Construct StringMap let arr["another array"] := ar_Construct Array ar_Erase arr["another array"] 0 ; erase element 0 if it exists, higher elements will be shifted down by 1 ar_Erase arr "begin":"end" ; erase any elements having keys >= "begin" and <= "end" The command arguments include more than just the passed parameters. They include the Script Object and a bunch of other data that all gets parsed out. The first of which is paraminfo, which has an array of arguments - one for each paramenter, with arg(0) being the first one, which is usually the array. It then uses the Script Token file to get the array ID of that passed array, and from there it can evaluate and erase. It evaluates fine when I call it from a script. That's not the problem. I can't figure out how to call it (or any of the sub-code) from within a .dll function that is looping through nested arrays of data. Because the arrays I am evaluating are nested, they are not included in the command arguments as parameters, and therefore cannot be treated as script tokens. If I could convert the array into a script token type that might work, but I have no idea how to do that.
  14. SDR adds nearly 60 new actor value categories in order for its advanced detection system to work. These get added to every NPC and Creature. That's a lot of extra data. If the data isn't cleared out for mods and references that are no longer active, there would be save game bloat that will eat up memory. And considering Oblivion's limitations when it comes to accessing and maintaining memory, I think that would be a bad thing. There could also be issues with mods that get uninstalled at some point and reinstalled later. The dynamic references array would be the worst one, since that data would constantly grow, and possible have incorrect data if ref IDs get reused (not sure how that works, or if that happens). If a mod gets uninstalled, I feel it is proper house keeping to wipe out any and all COVs data that is related to it. Same goes for any ref that is invalid or gets deleted. And since I've designed it to be used by other mods so that they can create their own COVs, that would impact what they do as well. Technically I do have the scripted solution. I just know from past experience that performance increases exponentially when I can move processes out of the scripts and into the .dll. If no one spots an easy solution, I will release it with the scripted clean up versions and hope for the best.
  15. Okay, hopefully this will help. See the attached .jpg as a visual aid. Let's say I want to assign a custom object value to an actor. The general format (more or less) is along these lines: callingRef.sdrSetCOVsNum GroupID "ValueKey" Value For example, I want to set the Player's hearing to type "2": PlayerRef.sdrSetCOVsNum 0 "iCOVsHearingType" 2 In the .dll, the following series of programmed events would take place: 1. Get the name of the Parent Mod of the calling ref using an internal function. In this case, that would be "Oblivion.esm". 2. Determine the base ref ID of the actor (last six hex digits of the eight), and convert to an integer (I think it's 20 in the case of the player ref). 3. Retrieve the master string map (tier 1) that stores everything by an ID that is captured and stored in a global on game load. 4. Find the Parent Mod key in the string map ("Oblivion.esm"), and retrieve the associated numeric map (tier 2) of base refs. If it isn't there, create a new key/value pair and populate the value with a new empty map. 5. Find the base ref (20) in the numeric map (tier 2), and retrieve the numeric map of COV Group IDs that are actively being used. If the base ref ID is missing, create a new key/value pair and populate the value with a new empty map. 6. Find the group ID (tier 3) that was passed in the function ("0" in the example above), and retrieve the data set of key/value pairs that belongs to it (tier 4). If the group ID is missing, create a new key/value pair and populate the value with a new empty string map. 7. Find the string value key ("iCOVsHearingType") (tier 5) and set the value of it to the passed value of the function (2). If the key is missing, create a new string key/value pair. The above example totally works with the current code in the .dll. And there are functions for getting/setting/modifying numbers, refs, and strings (no arrays for now) that can be called from scripts. But let's say that I wanted to *remove* a key/value pair of any kind. For example, let's say a mod is no longer in the active load order. I would want to delete that key value pair from the Master String Map, because all of that mod's refs would no longer be active, and so all the associated COV data would just be taking up space. Or let's say that a single reference has been deleted or is invalid (such as a dynamic randomly generated monster), then I would want to be able to remove that base ref ID key/value pair (and thus all the COV data associated with that ref). But there is no method programmed into the OBSE's Array Interface API that let's you remove a key/value pair. And every experiment I have tried with my limited knowledge and resources has failed. I have had to fall back on using scripts in my SDR.esm mod and the OBSE "ar_Erase" function in order to remove inactive mods and deleted/invalid refs. Those scripts do work. But I would *rather* do it in the .dll, because I would imagine the performance of rolling through all those records would be significantly higher in the .dll. Especially if someone has a heavy load order with mods that add lots of NPCs and creatures. But for the life of me, I can't figure out how to do it. And while I appreciate the suggestion for tracking the array IDs in another table, there's no method to get the array ID either - at least not as far as I could determine. I can create the array using the OBSE ArrayVar interface, and I can store the array. But I have no idea how I am supposed to determine what the ID of the array is once it is created. I have tried a number of methods (as stated in previous posts), and none of them have worked. If I could do that, that's half the problem solved right there, since the other array functions used to erase key/value pairs require the array ID.
×