• Content Count

  • Joined

  • Last visited

Community Reputation

5 Neutral

About TheBrain0110

  • Rank
    Junior Member
  1. Yeah, I found that out when I tried editing the temperature of buildings, and their PrimaryElement wasn't the same index as items. So I ended up using that same .find command, basing it off the one a couple lines above. Here's my current script, largely based on your example code, but spruced up just a little bit: const { readFileSync, writeFileSync } = require("fs"); const { parseSaveGame, writeSaveGame } = require("oni-save-parser"); // Put the name of your save file here const savename = "Regolith" function loadFile(fileName) { const fileData = readFileSync(`./${fileName}.sav`); return parseSaveGame(fileData.buffer); } function saveFile(fileName, save) { const fileData = writeSaveGame(save); writeFileSync(`./${fileName}.sav`, new Uint8Array(fileData)); console.log("Save File Written"); } function modifyItems(itemName, newMass, newTemp) { const items = saveData.gameObjects.find(x => === itemName); for (const item of items.gameObjects) { var element = item.behaviors.find(x => === "PrimaryElement"); if (newMass) {element.templateData.Units = newMass;} if (newTemp) {element.templateData._Temperature = newTemp;} } console.log(`${itemName} Processed`) } function checkItems(itemName) { const items = saveData.gameObjects.find(x => === itemName); for (const item of items.gameObjects) { var element = item.behaviors.find(x => === "PrimaryElement"); var mass = element.templateData.Units; var temp = element.templateData._Temperature; console.log(`${itemName} Mass: ${mass}`); console.log(`${itemName} Temp: ${temp}`); } } function printDataStructure(itemName) { const items = saveData.gameObjects.find(x => === itemName); for (const item of items.gameObjects) { console.log(`\n${itemName}`); console.log(item.behaviors); } } const saveData = loadFile(savename); console.log("Save File Parsed"); modifyItems("Regolith", 1, 10); checkItems("Regolith"); modifyItems("BunkerTile", null, 100); modifyItems("ExteriorWall", null, 100); modifyItems("SolarPanel", null, 100); modifyItems("Iron", null, 200) modifyItems("BunkerDoor", null, 100) modifyItems("GlassTile", null, 100) printDataStructure("BunkerDoor"); saveFile(`${savename}-pruned`, saveData); Source Should work on any Node v6.x+, just stick it in a new folder, do `npm install oni-save-parser`, and copy in the save file you want to work on and put its name in `savename = `. I like to keep things simple Of course, it's also so simple that the only things it can do right now are change an object's Temperature and Mass, since I was mostly focused on wrangling the Space biome into something manageable. (and changing the Units value on buildings will have unknown effects, they all seem to be 1, not their actual mass). But it should be pretty straightforward to add other specific values if someone wanted to adapt it for their own purposes. And it only touches a value if you give it a new one, hence why I pass `null` for the mass on the buildings. Then again if you add batch editing and macros to Duplicity, then that definitely supersedes my little script. I did add a little helper method to spit out the item.behaviors object to help find other fields worth editing, but navigating the tree in Duplicity is still the much easier way to poke around and find new things. So despite being pretty basic, I'm still proud of some little details. It was fun
  2. Can also confirm. Had a bunch of them after leaving my surface area alone for a while to work on other parts of the base. On the other hand, this is the only way that you'd end up with tiles of pure steel, and there seems to be some kind of easter egg hiding in there...
  3. After going away for a while and letting my brain think in the background, I realized that of course, PrimaryElement isn't a named element. That part is just an index, and then there's more named pairs inside that object. So the final value for the mass of an item is `item.behaviors[1].templateData.Units`. The final gotcha I ran into is the way JS handles variables as references (or doesn't). `var mass = item.behaviors[1].templateData.Units; mass = 1;` doesn't change anything. It has to be `item.behaviors[1].templateData.Units = 1;` Anyway, sorry about the rambling stream-of-consciousness. I started off thinking I was stuck and asking for help, then ended up just brute forcing my way to figuring it out. It's what happens when you kinda-sorta know what you're doing with programming in general, but aren't super experienced with any given language xD Maybe some of these notes will be helpful to others, I dunno...
  4. So, I was playing around with the vnext build of Duplicity a few days ago, and found the neat ability to change the mass, temp etc of items on the ground. It was under something like gameObjects > Dirt > #ID > behaviors > PrimaryElement > <object>. That was fun to play around with, have a couple kg of a resource item on the ground turn into a few tons is nice and all. Then I get the idea to do it the other way around, and turn the multi-ton balls of Regolith lying around everywhere in the Space biome into a manageable size. Except in the last couple days since, you've updated the Duplicity vnext editor to hide the <object> property under PrimaryElement, so I can't access the mass field at all now (I think it was called "unit(s?)"), even with the new "Advanced" mode turned on. On the other hand, there's hundreds of balls of Regolith lying around anyway, so the web editor would be extremely tedious to try and change them all. But a simple loop in a script should work perfectly! Start with `npm install oni-save-parser`, and cloning the git repo as well, so far so good. Except the example code in your GitHub repo Readme doesn't quite run as is in a fresh environment, the package imports are named wrong / missing. I'm not really a Node guy anyway, so I fumbled my way through a bit, but ended up with this: const fs = require("fs"); const { parseSaveGame, writeSaveGame } = require("oni-save-parser"); const savename = "Regolith" function loadFile(fileName) { const fileData = fs.readFileSync(`./${fileName}.sav`); return parseSaveGame(fileData.buffer); } function saveFile(fileName, save) { const fileData = writeSaveGame(save); fs.writeFileSync(`./${fileName}.sav`, new Uint8Array(fileData)); } const saveData = loadFile(savename); // Purge excess Regolith const items = saveData.gameObjects.find(x => === "Regolith"); console.log("Counting Items:") console.log(items.length) for (const item of items.gameObjects) { console.log("Mass:") console.log(item.behaviors.PrimaryElement.Units); //item.behaviors.PrimaryElement.Units = 1 //Set to 1kg, from the usually >10000 } //saveFile(`${savename}-tweaked`, saveData); (As I side note, my distro included an old v4.x of Nodejs by default, which didn't understand the `const {...} = require()` syntax at all. I ended up having to install a newer version. This is partly why I'm not a Node guy in the first place, I can't deal with dependency and versioning hell. That and sorting out whether I need to look at the JS files or the TypeScript ones, or not having the tools to convert between them... >.<) Now I at least got it running, and the only problem is... `items.length` is Undefined. `item.behaviors.PrimaryElement` is Undefined. I can't see into the data structure at all from the console, so I can't find the values I want to modify now. You mentioned working on a JSON export of the parsed data, that would help. But I can't quite figure out how to get started. Edit: Later, after more blind fiddling: So, `console.log(item.behaviors)` does give me a printout of the object, like this: [ { name: 'KPrefabID', templateData: { InstanceID: 2399929 }, extraData: undefined, extraRaw: undefined }, { name: 'PrimaryElement', templateData: { ElementID: 1362238252, _Temperature: 614.7877807617188, diseaseID: [Object], diseaseCount: 0, Units: 6555.6103515625 }, extraData: undefined, extraRaw: undefined }, { name: 'Pickupable', ... }, ... ] I tried `item.behaviors["PrimaryElement"].Units`, but that didn't work. I'm just not quite sure of the Javascript syntax for nested named array elements, and which level of nesting the objects are at.
  5. Given the thousands of tons of regolith that accumulate, I'd almost consider a way to get rid of it all a feature...