Jump to content

Ensrick

Members
  • Posts

    10
  • Joined

  • Last visited

Everything posted by Ensrick

  1. public static void updateLootXml(Document doc) { XPathFactory xPathfactory = XPathFactory.newInstance(); XPath xpath = xPathfactory.newXPath(); try { NodeList lootgroups = (NodeList) xpath.evaluate("//lootgroup[starts-with(@name, 'groupScrap')]", doc, XPathConstants.NODESET); for (int i = 0; i < lootgroups.getLength(); i++) { Node lootgroup = lootgroups.item(i); NodeList items = (NodeList) xpath.evaluate("item[starts-with(@name, 'resource')]", lootgroup, XPathConstants.NODESET); for (int j = 0; j < items.getLength(); j++) { Node item = items.item(j); String countStr = item.getAttributes().getNamedItem("count").getNodeValue().trim(); int minCount, maxCount; if (countStr.contains(",")) { String[] counts = countStr.split(","); minCount = Integer.parseInt(counts[0].trim()); maxCount = Integer.parseInt(counts[1].trim()) * 3; } else { minCount = Integer.parseInt(countStr); maxCount = minCount * 3; } String xpathStr = String.format("//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='%s']/@count", item.getAttributes().getNamedItem("name").getNodeValue()); String cmdStr = String.format("<set xpath=\"%s\">%d, %d</set>", xpathStr, minCount, maxCount); System.out.println(cmdStr); } } } catch (XPathExpressionException e) { e.printStackTrace(); } } I made this little method which takes the XML assigned to a Document type variable and prints out XPath commands that take any loot item which starts with the the name "groupScrap" and changes the max count of all items within it max count to x3; and if it's count is not separated by a comma, as in it has a count of 2, then it makes the max count 3x that. I should be able to build off of this method to make a program that outputs XPath commands that do all sorts of things for easily manipulating large amounts of existing items. Here is the output: <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceFishingWeight']/@count">1, 9</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceScrapLead']/@count">1, 60</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceScrapIron']/@count">1, 60</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceTrophy1']/@count">1, 15</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceTrophy2']/@count">1, 15</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceScrapBrass']/@count">40, 750</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceDoorKnob']/@count">1, 15</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceCandleStick']/@count">1, 6</set> <set xpath="//lootgroup[starts-with(@name, 'groupScrap')]/item[@name='resourceRadiator']/@count">1, 6</set> I got a simple UI to start.
  2. It's just placeholder text, the only thing that changed from line to line was which item in the @name='' by parsing the input XML and generating lines for every item with count attribute. As of right now the idea for the program is to input an XML by choosing it from the file system and then it will change something simple to start like the count attribute, and output a bunch of XPath expressions to the mod XML. Eventually, when I get a UI up, the idea is to have user options as to what the user wants to change. I'll figure what to do about other modlets once I have something better.
  3. That's still quite a bit of tedious work when I want to modify the entire loot system in several modlets among other modlets I want to make. Even if it takes me a lot longer to make a program, I think I'd prefer the added flexibility it gives me and the value it might have to other users. I making a program that parses the XML, identifies the elements to modify, then outputs a new xml with the desired modifications. It's pretty crude so far but I managed to get a working output file that contains hundreds of lines like this one: <set xpath="//item[@name='resourceFishingWeight']" attribute="count" value="format-number(number(@count) * 100, '###,###,###')"/> For every item that has a count. It's not at all efficient yet; but I it wasn't to difficult to make a program that made a node full of these shows promise. I just need to refine it and add more functionality. Of course, that line doesn't even work, but I just need to modify the StringBuilder strings.
  4. That's it? append set replace insertAfter insertBefore remove removeAll addIfMissing setIfMissing addIfNotPresent removeIfPresent removeIfAny selectSingleNode selectNodes Well that's a bit more limiting than the functionality XPath would otherwise allow. I'll try making a Java program for parsing the game's XML files and outputting an XML for modding. For now, I'll just keep it simple by just having it modify the "count" attribute, but it'll be something I can build on.
  5. These are all commands covered: append set replace insertAfter insertBefore remove removeAll addIfMissing setIfMissing addIfNotPresent removeIfPresent removeIfAny selectSingleNode selectNodes Now I have some idea of how to use each of these, however, this is rather limiting compared to what I would be able to do with the full functionality of XPath. I was using the XPath 3.1 WWWC specifications, guides, and such. There's a lot more that XPath could do if it weren't limited to those commands. Still, I think I'm pretty invested now. I'll try creating a simple Java program with a simple UI that takes XML as input and spits out an XML with these XPath commands.
  6. I've found an XPath tester online to see if the path is correct, so I tried the following path: //lootgroup[@name='groupScrapCommon' or @name='groupScrapUncommon' or @name='groupScrapRare']//item[@count] and it works, but when I try to change an attribute using an xpath operation like so: <modify xpath="//lootgroup//item[@count]" attribute="count" replace="format-number(number(@count) * 100, '###,###,###')"/> it doesn't actually change the count, though it produces no error. Is there a way I could find out what commands and operations are supported by 7D2D's XPath implementation?
  7. Thanks, I've been trying to familiarize myself with XPath now that I know it is a query language. Though this is all new to me, I think there might still be a way I can create an expression that utilizes XPath hooks to accomplish most of what I'm trying to do without going line by line and making using an XPath command per each change I want to make. I just tried this: <modify xpath="/hook[@file='loot.xml']/lootgroup[@name='groupScrapCommon' or @name='groupScrapUncommon' or @name='groupScrapRare']//item[@count]" attribute="count" replace="substring-before(@count, ',') + ',' + concat(floor(substring-after(@count, ',') * 2 div 5) * 5, '')"/> There were no errors, but I'd need to test more to see if it had the intended effect of multiplying the maximum loot count by 2 and rounding it down to the nearest 5. This is specifically meant to modify the lootgroup stacks for scrap. Is there a better way to test this, or do I just have to playtest by throwing massive numbers in there?
  8. Unity uses C#, but I have more experience doing simple things in Java. I could make a method to do this: using System.Xml; // Load the loot.xml file XmlDocument doc = new XmlDocument(); doc.Load("loot.xml"); // Find the item you want to modify (in this example,it is an item with a name attribute of "resourcePaper") XmlNode itemNode = doc.SelectSingleNode("//item[@name='resourcePaper']"); if (itemNode != null) { // Get the current count range string countRange = itemNode.Attributes["count"].Value; // Split the count range into min and max values string[] countValues = countRange.Split(','); int currentMinCount = int.Parse(countValues[0]); int currentMaxCount = int.Parse(countValues[1]); // Update the max count to be 3x its current amount, with a minimum value of 10 int newMaxCount = UpdateCount(currentMaxCount, 10); // Update the count range attribute to the new values itemNode.Attributes["count"].Value = currentMinCount.ToString() + "," + newMaxCount.ToString(); // Save the modified loot.xml file doc.Save("loot.xml"); } But I have no idea how to make use of this within a script. I'll try fixing my issue with the ')' you pointed out. That's silly of me from copy/pasting. I just don't prefer that method for large edits to the loot file. I think with Unity there is a way I could just name it loot_override.xml and copy/paste the loot.xml stuff and make my edits that way. EDIT: the fixes you recommended worked. I was thinking, I might be able to create a little Java program or something to make sweeping changes to the XML files because it looks like it'll take me forever either way.
  9. The following are two examples that I've tried. The first one does seem to work, but not without issues at times. I want to break down the loot mod I'm working on into modlets so that users can choose which ones they want. Removing things seems to cause conflicts with mods that use nodes. It could be I'm doing it wrong though. I can use insertAfter successfully when not trying to replace existing nodes by removing them and that seems fine and doesn't seem to cause conflicts. <remove xpath="/lootcontainers/lootgroup[@name='groupScrapCommon']"/> <insertAfter xpath="/lootcontainers/lootqualitytemplates"> <!-- Resources_Scrap --> <lootgroup name="groupScrapCommon" count="1"> <item name="resourceFishingWeight" count ="1,9"/> <item name="resourceScrapLead" count ="1,40"/> <item name="drinkCanEmpty" count ="1,6"/> <item name="resourceScrapIron" count ="1,40"/> </lootgroup> </insertAfter> The second method here is the xpath override; slow and tedious for large changes, but I've had it work when I use it to tweak item properties. What I've tried here doesn't even work, and the error in the log indicates the way I've pathed it or the syntax is not accurate, but I'm not sure how to do it correctly. Here's an example of how I'd use it to increase the ceiling on the number of fishing weights in a junk pile. <set xpath="/lootcontainers/lootgroup[@name='resourceScrapCommon')]/item[contains(@name, 'resourceFishingWeight')]/@count">1,5</set> Also, couple of other questions. There are many items for which I want to simply make a small change like 1.5 more maximum loot count for specific items without changing the minimum amount. Surely there must be a way to make sweeping changes like that.
  10. I'm familiar with tweaking the contents of XML files from various games, however, I want to take my changes and package them as a mod. To my understanding, this requires some "set xpath="..." method or I have to remove the nodes I want to modify and use a node like "<insertAfter/> with all of my modified changes. So far, neither has worked without complications; and I don't like to remove existing nodes because there could compatibility problems with mods. The syntax for the XPath method evades me and with so many tiny changes it is extremely tedious and inefficient. Here's what I'm doing to the loot.xml: 1. Adding a chance for items to have certain mods. 2. Adding chances for containers to contain higher amounts of loot. 3. Adding chances for containers to have more loot in their inventory slots than they might otherwise For example: 1. Making the Beretta have a 15% chance to have a mod. (Also, this is just an example, but I want to do this for every item that can have mods) <item name="gunHandgunT1Pistol" mods="barrelAttachments,sideAttachments,smallTopAttachments,scope,trigger" mod_chance=".15"/> 2. In this example, just making the book piles that normally have 1-5 paper instead have 1 to 50, but at a reduced chance for the higher amounts. <lootgroup name="groupBookPile01"> <item name="resourcePaper" count="1,5" loot_prob_template="high"/> <item name="resourcePaper" count="5,15" loot_prob_template="medHigh"/> <item name="resourcePaper" count="15,25" loot_prob_template="med"/> <item name="resourcePaper" count="25,50" loot_prob_template="medLow"/> </lootgroup> 3. In this example, I just want more books/schematics of various types, but at a lower probability for each additional book. The thing is, I want to modify almost every loot group to allow containers to have more loot in each slot, including more varied loot at a reduced chance for each additional slot having loot. <lootgroup name="groupBookPile02"> <item group="booksAllScaled"/> </lootgroup> <lootgroup name="groupBookPile" count="all"> <item group="groupBookPile01" count="1"/> <item group="groupBookPile02" loot_prob_template="high" force_prob="true"/> <item group="groupBookPile02" loot_prob_template="medHigh" force_prob="true"/> <item group="groupBookPile02" loot_prob_template="med" force_prob="true"/> <item group="groupBookPile02" loot_prob_template="medLow" force_prob="true"/> <item group="groupBookPile02" loot_prob_template="low" force_prob="true"/> <item group="groupBookPile02" loot_prob_template="veryLow" force_prob="true"/> </lootgroup>
×
×
  • Create New...