825 lines
21 KiB
Go
825 lines
21 KiB
Go
package processor
|
|
|
|
import (
|
|
"cook/utils"
|
|
"testing"
|
|
)
|
|
|
|
func TestSurgicalJSONEditing(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
content string
|
|
luaCode string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "Modify single field",
|
|
content: `{
|
|
"name": "test",
|
|
"value": 42,
|
|
"description": "original"
|
|
}`,
|
|
luaCode: `
|
|
data.value = 84
|
|
modified = true
|
|
`,
|
|
expected: `{
|
|
"name": "test",
|
|
"value": 84,
|
|
"description": "original"
|
|
}`,
|
|
},
|
|
{
|
|
name: "Add new field",
|
|
content: `{
|
|
"name": "test",
|
|
"value": 42
|
|
}`,
|
|
luaCode: `
|
|
data.newField = "added"
|
|
modified = true
|
|
`,
|
|
expected: `{
|
|
"name": "test",
|
|
"value": 42
|
|
,"newField":"added"}`, // sjson.Set() adds new fields in compact format
|
|
},
|
|
{
|
|
name: "Modify nested field",
|
|
content: `{
|
|
"config": {
|
|
"settings": {
|
|
"enabled": false,
|
|
"timeout": 30
|
|
}
|
|
}
|
|
}`,
|
|
luaCode: `
|
|
data.config.settings.enabled = true
|
|
data.config.settings.timeout = 60
|
|
modified = true
|
|
`,
|
|
expected: `{
|
|
"config": {
|
|
"settings": {
|
|
"enabled": true,
|
|
"timeout": 60
|
|
}
|
|
}
|
|
}`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
command := utils.ModifyCommand{
|
|
Name: "test",
|
|
Lua: tt.luaCode,
|
|
}
|
|
|
|
commands, err := ProcessJSON(tt.content, command, "test.json")
|
|
if err != nil {
|
|
t.Fatalf("ProcessJSON failed: %v", err)
|
|
}
|
|
|
|
if len(commands) == 0 {
|
|
t.Fatal("Expected at least one command")
|
|
}
|
|
|
|
// Apply the commands
|
|
result := tt.content
|
|
for _, cmd := range commands {
|
|
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
|
}
|
|
|
|
// Check the actual result matches expected
|
|
if result != tt.expected {
|
|
t.Errorf("Expected:\n%s\n\nGot:\n%s", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSurgicalJSONPreservesFormatting(t *testing.T) {
|
|
// Test that surgical editing preserves the original formatting structure
|
|
content := `{
|
|
"Defaults": {
|
|
"Behaviour": "None",
|
|
"Description": "",
|
|
"DisplayName": "",
|
|
"FlavorText": "",
|
|
"Icon": "None",
|
|
"MaxStack": 1,
|
|
"Override_Glow_Icon": "None",
|
|
"Weight": 0,
|
|
"bAllowZeroWeight": false
|
|
},
|
|
"RowStruct": "/Script/Icarus.ItemableData",
|
|
"Rows": [
|
|
{
|
|
"Description": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-Description\", \"A bundle of soft fiber, highly useful.\")",
|
|
"DisplayName": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-DisplayName\", \"Fiber\")",
|
|
"FlavorText": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-FlavorText\", \"Fiber is collected from bast, the strong inner bark of certain flowering plants.\")",
|
|
"Icon": "/Game/Assets/2DArt/UI/Items/Item_Icons/Resources/ITEM_Fibre.ITEM_Fibre",
|
|
"MaxStack": 1000000,
|
|
"Name": "Item_Fiber",
|
|
"Weight": 10
|
|
}
|
|
]
|
|
}`
|
|
|
|
expected := `{
|
|
"Defaults": {
|
|
"Behaviour": "None",
|
|
"Description": "",
|
|
"DisplayName": "",
|
|
"FlavorText": "",
|
|
"Icon": "None",
|
|
"MaxStack": 1,
|
|
"Override_Glow_Icon": "None",
|
|
"Weight": 0,
|
|
"bAllowZeroWeight": false
|
|
},
|
|
"RowStruct": "/Script/Icarus.ItemableData",
|
|
"Rows": [
|
|
{
|
|
"Description": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-Description\", \"A bundle of soft fiber, highly useful.\")",
|
|
"DisplayName": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-DisplayName\", \"Fiber\")",
|
|
"FlavorText": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-FlavorText\", \"Fiber is collected from bast, the strong inner bark of certain flowering plants.\")",
|
|
"Icon": "/Game/Assets/2DArt/UI/Items/Item_Icons/Resources/ITEM_Fibre.ITEM_Fibre",
|
|
"MaxStack": 1000000,
|
|
"Name": "Item_Fiber",
|
|
"Weight": 500
|
|
}
|
|
]
|
|
}`
|
|
|
|
command := utils.ModifyCommand{
|
|
Name: "test",
|
|
Lua: `
|
|
-- Modify the weight of the first item
|
|
data.Rows[1].Weight = 500
|
|
modified = true
|
|
`,
|
|
}
|
|
|
|
commands, err := ProcessJSON(content, command, "test.json")
|
|
if err != nil {
|
|
t.Fatalf("ProcessJSON failed: %v", err)
|
|
}
|
|
|
|
if len(commands) == 0 {
|
|
t.Fatal("Expected at least one command")
|
|
}
|
|
|
|
// Apply the commands
|
|
result := content
|
|
for _, cmd := range commands {
|
|
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
|
}
|
|
|
|
// Check that the result matches expected (preserves formatting and changes weight)
|
|
if result != expected {
|
|
t.Errorf("Expected:\n%s\n\nGot:\n%s", expected, result)
|
|
}
|
|
}
|
|
|
|
func TestSurgicalJSONPreservesFormatting2(t *testing.T) {
|
|
// Test that surgical editing preserves the original formatting structure
|
|
content := `
|
|
{
|
|
"RowStruct": "/Script/Icarus.ProcessorRecipe",
|
|
"Defaults": {
|
|
"bForceDisableRecipe": false,
|
|
"Requirement": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_Talents"
|
|
},
|
|
"SessionRequirement": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_CharacterFlags"
|
|
},
|
|
"CharacterRequirement": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_CharacterFlags"
|
|
},
|
|
"RequiredMillijoules": 2500,
|
|
"RecipeSets": [],
|
|
"ResourceCostMultipliers": [],
|
|
"Inputs": [
|
|
{
|
|
"Element": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_ItemsStatic"
|
|
},
|
|
"Count": 1,
|
|
"DynamicProperties": []
|
|
}
|
|
],
|
|
"Container": {
|
|
"Value": "None"
|
|
},
|
|
"ResourceInputs": [],
|
|
"bSelectOutputItemRandomly": false,
|
|
"bContainsContainer": false,
|
|
"ItemIconOverride": {
|
|
"ItemStaticData": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_ItemsStatic"
|
|
},
|
|
"ItemDynamicData": [],
|
|
"ItemCustomStats": [],
|
|
"CustomProperties": {
|
|
"StaticWorldStats": [],
|
|
"StaticWorldHeldStats": [],
|
|
"Stats": [],
|
|
"Alterations": [],
|
|
"LivingItemSlots": []
|
|
},
|
|
"DatabaseGUID": "",
|
|
"ItemOwnerLookupId": -1,
|
|
"RuntimeTags": {
|
|
"GameplayTags": []
|
|
}
|
|
},
|
|
"Outputs": [
|
|
{
|
|
"Element": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_ItemTemplate"
|
|
},
|
|
"Count": 1,
|
|
"DynamicProperties": []
|
|
}
|
|
],
|
|
"ResourceOutputs": [],
|
|
"Refundable": "Inherit",
|
|
"ExperienceMultiplier": 1,
|
|
"Audio": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_CraftingAudioData"
|
|
}
|
|
},
|
|
"Rows": [
|
|
{
|
|
"Name": "Biofuel1",
|
|
"RecipeSets": [
|
|
{
|
|
"RowName": "Composter",
|
|
"DataTableName": "D_RecipeSets"
|
|
}
|
|
],
|
|
"Inputs": [
|
|
{
|
|
"Element": {
|
|
"RowName": "Raw_Meat",
|
|
"DataTableName": "D_ItemsStatic"
|
|
},
|
|
"Count": 2,
|
|
"DynamicProperties": []
|
|
},
|
|
{
|
|
"Element": {
|
|
"RowName": "Tree_Sap",
|
|
"DataTableName": "D_ItemsStatic"
|
|
},
|
|
"Count": 1,
|
|
"DynamicProperties": []
|
|
}
|
|
],
|
|
"Outputs": [],
|
|
"Audio": {
|
|
"RowName": "Composter"
|
|
},
|
|
"ResourceOutputs": [
|
|
{
|
|
"Type": {
|
|
"Value": "Biofuel"
|
|
},
|
|
"RequiredUnits": 100
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
`
|
|
|
|
expected := `
|
|
{
|
|
"RowStruct": "/Script/Icarus.ProcessorRecipe",
|
|
"Defaults": {
|
|
"bForceDisableRecipe": false,
|
|
"Requirement": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_Talents"
|
|
},
|
|
"SessionRequirement": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_CharacterFlags"
|
|
},
|
|
"CharacterRequirement": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_CharacterFlags"
|
|
},
|
|
"RequiredMillijoules": 2500,
|
|
"RecipeSets": [],
|
|
"ResourceCostMultipliers": [],
|
|
"Inputs": [
|
|
{
|
|
"Element": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_ItemsStatic"
|
|
},
|
|
"Count": 1,
|
|
"DynamicProperties": []
|
|
}
|
|
],
|
|
"Container": {
|
|
"Value": "None"
|
|
},
|
|
"ResourceInputs": [],
|
|
"bSelectOutputItemRandomly": false,
|
|
"bContainsContainer": false,
|
|
"ItemIconOverride": {
|
|
"ItemStaticData": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_ItemsStatic"
|
|
},
|
|
"ItemDynamicData": [],
|
|
"ItemCustomStats": [],
|
|
"CustomProperties": {
|
|
"StaticWorldStats": [],
|
|
"StaticWorldHeldStats": [],
|
|
"Stats": [],
|
|
"Alterations": [],
|
|
"LivingItemSlots": []
|
|
},
|
|
"DatabaseGUID": "",
|
|
"ItemOwnerLookupId": -1,
|
|
"RuntimeTags": {
|
|
"GameplayTags": []
|
|
}
|
|
},
|
|
"Outputs": [
|
|
{
|
|
"Element": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_ItemTemplate"
|
|
},
|
|
"Count": 1,
|
|
"DynamicProperties": []
|
|
}
|
|
],
|
|
"ResourceOutputs": [],
|
|
"Refundable": "Inherit",
|
|
"ExperienceMultiplier": 1,
|
|
"Audio": {
|
|
"RowName": "None",
|
|
"DataTableName": "D_CraftingAudioData"
|
|
}
|
|
},
|
|
"Rows": [
|
|
{
|
|
"Name": "Biofuel1",
|
|
"RecipeSets": [
|
|
{
|
|
"RowName": "Composter",
|
|
"DataTableName": "D_RecipeSets"
|
|
}
|
|
],
|
|
"Inputs": [
|
|
{
|
|
"Element": {
|
|
"RowName": "Raw_Meat",
|
|
"DataTableName": "D_ItemsStatic"
|
|
},
|
|
"Count": 2,
|
|
"DynamicProperties": []
|
|
}
|
|
],
|
|
"Outputs": [],
|
|
"Audio": {
|
|
"RowName": "Composter"
|
|
},
|
|
"ResourceOutputs": [
|
|
{
|
|
"Type": {
|
|
"Value": "Biofuel"
|
|
},
|
|
"RequiredUnits": 100
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
`
|
|
|
|
command := utils.ModifyCommand{
|
|
Name: "test",
|
|
Lua: `
|
|
-- Define regex patterns for matching recipe names
|
|
local function matchesPattern(name, pattern)
|
|
local matches = re(pattern, name)
|
|
-- Check if matches table has any content (index 0 or 1 should exist if there's a match)
|
|
return matches and (matches[0] or matches[1])
|
|
end
|
|
|
|
-- Selection pattern for recipes that get multiplied
|
|
local selectionPattern = "(?-s)(Bulk_)?(Pistol|Rifle).*?Round.*?|(Carbon|Composite)_Paste.*|(Gold|Copper)_Wire|(Ironw|Copper)_Nail|(Platinum|Steel|Cold_Steel|Titanium)_Ingot|.*?Shotgun_Shell.*?|.*_Arrow|.*_Bolt|.*_Fertilizer_?\\d*|.*_Grenade|.*_Pill|.*_Tonic|Aluminum|Ammo_Casing|Animal_Fat|Carbon_Fiber|Composites|Concrete_Mix|Cured_Leather_?\\d?|Electronics|Epoxy_?\\d?|Glass\\d?|Gunpowder\\w*|Health_.*|Titanium_Plate|Organic_Resin|Platinum_Sheath|Refined_[a-zA-Z]+|Rope|Shotgun_Casing|Steel_Bloom\\d?|Tree_Sap\\w*"
|
|
|
|
-- Ingot pattern for recipes that get count set to 1
|
|
local ingotPattern = "(?-s)(Platinum|Steel|Cold_Steel|Titanium)_Ingot|Aluminum|Refined_[a-zA-Z]+|Glass\\d?"
|
|
|
|
local factor = 16
|
|
local bonus = 0.5
|
|
|
|
for _, row in ipairs(data.Rows) do
|
|
local recipeName = row.Name
|
|
|
|
-- Special case: Biofuel recipes - remove Tree_Sap input
|
|
if string.find(recipeName, "Biofuel") then
|
|
if row.Inputs then
|
|
for i = #row.Inputs, 1, -1 do
|
|
local input = row.Inputs[i]
|
|
if input.Element and input.Element.RowName and string.find(input.Element.RowName, "Tree_Sap") then
|
|
table.remove(row.Inputs, i)
|
|
print("Removing input 'Tree_Sap' from processor recipe '" .. recipeName .. "'")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Ingot recipes: set input and output counts to 1
|
|
if matchesPattern(recipeName, ingotPattern) then
|
|
if row.Inputs then
|
|
for _, input in ipairs(row.Inputs) do
|
|
input.Count = 1
|
|
end
|
|
end
|
|
if row.Outputs then
|
|
for _, output in ipairs(row.Outputs) do
|
|
output.Count = 1
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Selected recipes: multiply inputs by factor, outputs by factor * (1 + bonus)
|
|
if matchesPattern(recipeName, selectionPattern) then
|
|
if row.Inputs then
|
|
for _, input in ipairs(row.Inputs) do
|
|
local oldCount = input.Count
|
|
input.Count = input.Count * factor
|
|
print("Recipe " .. recipeName .. " Input.Count: " .. oldCount .. " -> " .. input.Count)
|
|
end
|
|
end
|
|
|
|
if row.Outputs then
|
|
for _, output in ipairs(row.Outputs) do
|
|
local oldCount = output.Count
|
|
output.Count = math.floor(output.Count * factor * (1 + bonus))
|
|
print("Recipe " .. recipeName .. " Output.Count: " .. oldCount .. " -> " .. output.Count)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
`,
|
|
}
|
|
|
|
commands, err := ProcessJSON(content, command, "test.json")
|
|
if err != nil {
|
|
t.Fatalf("ProcessJSON failed: %v", err)
|
|
}
|
|
|
|
if len(commands) == 0 {
|
|
t.Fatal("Expected at least one command")
|
|
}
|
|
|
|
// Apply the commands
|
|
result := content
|
|
for _, cmd := range commands {
|
|
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
|
}
|
|
|
|
// Check that the result matches expected (preserves formatting and changes weight)
|
|
if result != expected {
|
|
t.Errorf("Expected:\n%s\n\nGot:\n%s", expected, result)
|
|
}
|
|
}
|
|
|
|
func TestRetardedJSONEditing(t *testing.T) {
|
|
original := `{
|
|
"RowStruct": "/Script/Icarus.ItemableData",
|
|
"Defaults": {
|
|
"Behaviour": "None",
|
|
"DisplayName": "",
|
|
"Icon": "None",
|
|
"Override_Glow_Icon": "None",
|
|
"Description": "",
|
|
"FlavorText": "",
|
|
"Weight": 0,
|
|
"bAllowZeroWeight": false,
|
|
"MaxStack": 1
|
|
},
|
|
"Rows": [
|
|
{
|
|
"DisplayName": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-DisplayName\", \"Fiber\")",
|
|
"Icon": "/Game/Assets/2DArt/UI/Items/Item_Icons/Resources/ITEM_Fibre.ITEM_Fibre",
|
|
"Description": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-Description\", \"A bundle of soft fiber, highly useful.\")",
|
|
"FlavorText": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-FlavorText\", \"Fiber is collected from bast, the strong inner bark of certain flowering plants.\")",
|
|
"Weight": 10,
|
|
"MaxStack": 200,
|
|
"Name": "Item_Fiber"
|
|
}
|
|
]
|
|
}`
|
|
|
|
expected := `{
|
|
"RowStruct": "/Script/Icarus.ItemableData",
|
|
"Defaults": {
|
|
"Behaviour": "None",
|
|
"DisplayName": "",
|
|
"Icon": "None",
|
|
"Override_Glow_Icon": "None",
|
|
"Description": "",
|
|
"FlavorText": "",
|
|
"Weight": 0,
|
|
"bAllowZeroWeight": false,
|
|
"MaxStack": 1
|
|
},
|
|
"Rows": [
|
|
{
|
|
"DisplayName": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-DisplayName\", \"Fiber\")",
|
|
"Icon": "/Game/Assets/2DArt/UI/Items/Item_Icons/Resources/ITEM_Fibre.ITEM_Fibre",
|
|
"Description": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-Description\", \"A bundle of soft fiber, highly useful.\")",
|
|
"FlavorText": "NSLOCTEXT(\"D_Itemable\", \"Item_Fiber-FlavorText\", \"Fiber is collected from bast, the strong inner bark of certain flowering plants.\")",
|
|
"Weight": 10,
|
|
"MaxStack": 1000000,
|
|
"Name": "Item_Fiber"
|
|
}
|
|
]
|
|
}`
|
|
|
|
command := utils.ModifyCommand{
|
|
Name: "test",
|
|
Lua: `
|
|
for _, row in ipairs(data.Rows) do
|
|
if row.MaxStack then
|
|
if string.find(row.Name, "Carrot") or string.find(row.Name, "Potato") then
|
|
row.MaxStack = 25
|
|
else
|
|
row.MaxStack = row.MaxStack * 10000
|
|
if row.MaxStack > 1000000 then
|
|
row.MaxStack = 1000000
|
|
end
|
|
end
|
|
end
|
|
end
|
|
`,
|
|
}
|
|
|
|
commands, err := ProcessJSON(original, command, "test.json")
|
|
if err != nil {
|
|
t.Fatalf("ProcessJSON failed: %v", err)
|
|
}
|
|
|
|
if len(commands) == 0 {
|
|
t.Fatal("Expected at least one command")
|
|
}
|
|
|
|
// Apply the commands
|
|
result := original
|
|
for _, cmd := range commands {
|
|
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
|
}
|
|
|
|
// Check that the weight was changed
|
|
if result != expected {
|
|
t.Errorf("Expected:\n%s\nGot:\n%s", expected, result)
|
|
}
|
|
}
|
|
|
|
|
|
func TestRetardedJSONEditing2(t *testing.T) {
|
|
original := `
|
|
{
|
|
"Rows": [
|
|
{
|
|
"Name": "Deep_Mining_Drill_Biofuel",
|
|
"Meshable": {
|
|
"RowName": "Mesh_Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Itemable": {
|
|
"RowName": "Item_Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Interactable": {
|
|
"RowName": "Deployable"
|
|
},
|
|
"Focusable": {
|
|
"RowName": "Focusable_1H"
|
|
},
|
|
"Highlightable": {
|
|
"RowName": "Generic"
|
|
},
|
|
"Actionable": {
|
|
"RowName": "Deployable"
|
|
},
|
|
"Usable": {
|
|
"RowName": "Place"
|
|
},
|
|
"Deployable": {
|
|
"RowName": "Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Durable": {
|
|
"RowName": "Deployable_750"
|
|
},
|
|
"Inventory": {
|
|
"RowName": "Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Decayable": {
|
|
"RowName": "Decay_MetaItem"
|
|
},
|
|
"Generator": {
|
|
"RowName": "Deep_Mining_Biofuel_Drill"
|
|
},
|
|
"Resource": {
|
|
"RowName": "Simple_Internal_Flow_Only"
|
|
},
|
|
"Manual_Tags": {
|
|
"GameplayTags": [
|
|
{
|
|
"TagName": "Item.Machine"
|
|
}
|
|
]
|
|
},
|
|
"Generated_Tags": {
|
|
"GameplayTags": [
|
|
{
|
|
"TagName": "Item.Machine"
|
|
},
|
|
{
|
|
"TagName": "Traits.Meshable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Itemable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Interactable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Highlightable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Actionable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Usable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Deployable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Durable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Inventory"
|
|
}
|
|
],
|
|
"ParentTags": []
|
|
}
|
|
}
|
|
]
|
|
}
|
|
`
|
|
|
|
expected := `
|
|
{
|
|
"Rows": [
|
|
{
|
|
"Name": "Deep_Mining_Drill_Biofuel",
|
|
"Meshable": {
|
|
"RowName": "Mesh_Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Itemable": {
|
|
"RowName": "Item_Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Interactable": {
|
|
"RowName": "Deployable"
|
|
},
|
|
"Focusable": {
|
|
"RowName": "Focusable_1H"
|
|
},
|
|
"Highlightable": {
|
|
"RowName": "Generic"
|
|
},
|
|
"Actionable": {
|
|
"RowName": "Deployable"
|
|
},
|
|
"Usable": {
|
|
"RowName": "Place"
|
|
},
|
|
"Deployable": {
|
|
"RowName": "Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Durable": {
|
|
"RowName": "Deployable_750"
|
|
},
|
|
"Inventory": {
|
|
"RowName": "Deep_Mining_Drill_Biofuel"
|
|
},
|
|
"Decayable": {
|
|
"RowName": "Decay_MetaItem"
|
|
},
|
|
"Generator": {
|
|
"RowName": "Deep_Mining_Biofuel_Drill"
|
|
},
|
|
"Resource": {
|
|
"RowName": "Simple_Internal_Flow_Only"
|
|
},
|
|
"Manual_Tags": {
|
|
"GameplayTags": [
|
|
{
|
|
"TagName": "Item.Machine"
|
|
}
|
|
]
|
|
},
|
|
"Generated_Tags": {
|
|
"GameplayTags": [
|
|
{
|
|
"TagName": "Item.Machine"
|
|
},
|
|
{
|
|
"TagName": "Traits.Meshable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Itemable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Interactable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Highlightable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Actionable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Usable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Deployable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Durable"
|
|
},
|
|
{
|
|
"TagName": "Traits.Inventory"
|
|
}
|
|
],
|
|
"ParentTags": []
|
|
}
|
|
,"AdditionalStats": {
|
|
"(Value=\"BaseDeepMiningDrillSpeed_+%\")": 4000
|
|
}
|
|
}
|
|
]
|
|
}
|
|
`
|
|
|
|
command := utils.ModifyCommand{
|
|
Name: "test",
|
|
Lua: `
|
|
for i, row in ipairs(data.Rows) do
|
|
-- Special case: Deep_Mining_Drill_Biofuel
|
|
if string.find(row.Name, "Deep_Mining_Drill_Biofuel") then
|
|
print("[DEBUG] Special case: Deep_Mining_Drill_Biofuel")
|
|
if not row.AdditionalStats then
|
|
print("[DEBUG] Creating AdditionalStats table for Deep_Mining_Drill_Biofuel")
|
|
row.AdditionalStats = {}
|
|
end
|
|
print("[DEBUG] Setting BaseDeepMiningDrillSpeed_+% to 4000")
|
|
row.AdditionalStats["(Value=\\\"BaseDeepMiningDrillSpeed_+%\\\")"] = 4000
|
|
end
|
|
end
|
|
`,
|
|
}
|
|
|
|
commands, err := ProcessJSON(original, command, "test.json")
|
|
if err != nil {
|
|
t.Fatalf("ProcessJSON failed: %v", err)
|
|
}
|
|
|
|
if len(commands) == 0 {
|
|
t.Fatal("Expected at least one command")
|
|
}
|
|
|
|
// Apply the commands
|
|
result := original
|
|
for _, cmd := range commands {
|
|
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
|
}
|
|
|
|
// Check that the weight was changed
|
|
if result != expected {
|
|
t.Errorf("Expected:\n%s\nGot:\n%s", expected, result)
|
|
}
|
|
} |