Jump to content

[Tutorial] Adding Items to a Store


Recommended Posts

Hello there!

It's two years in the future here, how's thing way back when?

 

Thanks for this info.

 

I wanted to ask some advice - I'm trying to add something to the starting cupboard.

I've identified it as : 546e5d97-c234-46dc-9439-b23aafc02198

... and the thing I want to add is my custom item, so that guid goes into a custom LL (LootList) with just one item in it.

 

I only want the item to appear in the cupboard once, so I did this;

                    "RunOnlyOnce": "true",
                    "SucceedOnlyOnce": "true",

 

and I put the lootlist GUID into the CGenerateLootListInto value

 

What makes the MoScriptHook get run by the game? Does it go in a special folder?

Link to comment
Share on other sites

18 hours ago, Svartypops said:

What makes the MoScriptHook get run by the game? Does it go in a special folder?

It just needs to be anywhere game data can be loaded from (e.g. anywhere in a mod folder). If the game data object is loaded, it will be run when appropriate.

  • Thanks 1
Link to comment
Share on other sites

On 6/14/2021 at 7:35 PM, BMac said:

It just needs to be anywhere game data can be loaded from (e.g. anywhere in a mod folder). If the game data object is loaded, it will be run when appropriate.

Thank you very much for this.

 

I've been putting items in existing lootlists by just putting one item under the existing header - is that possible, or does it overwrite the existing lootlist with mine?
I'm rather confused how this "put what you want to change in the mod" thing works because ... how can you remove things from an existing list? So my guess is that I overwrite the whole of whatever currently exists with whatever I put in brackets?  But that can't be true either ...  my mind is tying itself in knots.

Edited by Svartypops
Link to comment
Share on other sites

Your last sentence is correct.  If you put any object in a bundle file in your mod folder, it throws out any already-existing object with that "ID" and replaces it with what you have in your file.  Putting only the new entries you want to add in your override loot list will actually replace the entire loot list with only those.  You'd have to copy over the existing data and then add or remove from that.  That's part of why ModScriptHookGameData is useful; it lets you make changes to store loot without copying and overriding entire loot lists.

  • Like 2
Link to comment
Share on other sites

4 hours ago, BMac said:

Your last sentence is correct.  If you put any object in a bundle file in your mod folder, it throws out any already-existing object with that "ID" and replaces it with what you have in your file.  Putting only the new entries you want to add in your override loot list will actually replace the entire loot list with only those.  You'd have to copy over the existing data and then add or remove from that.  That's part of why ModScriptHookGameData is useful; it lets you make changes to store loot without copying and overriding entire loot lists.

Perfect, this completely clears this up for me.

I'll see what I can do about tweaking my mod to adjust the existing loot lists, because just overwriting the original one is bad for compatibility.

 

Thank you very much BMac ❤️

 

Ah... seems I can't substitute the LootList for the container in the first post. That's a shame. I'll have to be the overwriting method, after all.

Edited by Svartypops
  • Thanks 1
Link to comment
Share on other sites

  • 6 months later...

Hello and a happy new year!

 

I tried everything possible to add my custom item to a crate / vendor / body, but unfortunately it will not appear. I hope someone can help me out...

The folder structure is like in the tutorial; the item itself works fine, itemmod and abilities are linked together. The following code is in one file; abilities and statuseffects in 2 seperate ones. (I think this is only for formatting; the variables handle everthing else. I saw mods where everything is in one file and it works just fine. But for educational reasons I wanted to stay with the original file structure).

Spoiler
{
	"GameDataObjects": [
	{
		"$type": "Game.GameData.EquippableGameData, Assembly-CSharp",
		"DebugName": "MOD_Abydons_Ring_Item",
		"ID": "f77813b4-0cee-437f-8128-07391fea2e05",
		"Components": [{
			"$type": "Game.GameData.ItemComponent, Assembly-CSharp",
			"DisplayName": 20525,
			"DescriptionText": 20526,
			"FilterType": "Clothing",
			"InventoryAudioEventListID": "c607cfb4-6130-4827-87f4-fac4c95a3e02",
			"IsQuestItem": "false",
			"IsIngredient": "false",
			"IsCurrency": "false",
			"IsAdventuringItem": "false",
			"IsJunk": "false",
			"CanSellForFullValue": "true",
			"MaxStackSize": 1,
			"NeverDropAsLoot": "false",
			"CanBePickpocketed": "true",
			"IsUnique": "true",
			"Value": 37500,
			"IconTextureSmall": "gui/icons/items/jewelry/ring_harmony_s.png",
			"IconTextureLarge": "gui/icons/items/jewelry/ring_harmony_l.png",
			"PencilSketchTexture": "",
			"InspectOnUseButton": [],
			"IsPlaceholder": "false"
		},
		{
			"$type": "Game.GameData.EquippableComponent, Assembly-CSharp",
			"EquipmentType": "None",
			"EquipmentSlot": "RingAnyHand",
			"AppearancePiece": {
				"ModelVisualDataPath": ""
			},

			"ItemModsIDs": ["9fe3c993-dbd0-4781-af66-d8333b49f903"],

			"OnEquipVisualEffects": [],
			"RestrictedToClassIDs": [],
			"RestrictedToPlayer": "false",
			"EquipConditionals": {
				"Operator": 0,
				"Components": []
			},
			"ProficientAbilityID": "00000000-0000-0000-0000-000000000000",
			"CannotUnequip": "false",
			"ItemRendererPrefab": "",
			"ItemModel": "",
			"AnimationController": "",
			"PaperdollOverrideRenderer": "",
			"AttackSummonID": "00000000-0000-0000-0000-000000000000",
			"CannotSheathe": "false",
			"PropVisualEffects": []
		}]
	},
	{
		"$type": "Game.GameData.ItemModGameData, Assembly-CSharp",
		"DebugName": "MOD_Abydons_Ring_Mod",
		"ID": "9fe3c993-dbd0-4781-af66-d8333b49f903",
		"Components": [{
			"$type": "Game.GameData.ItemModComponent, Assembly-CSharp",
			"DisplayName": 20525,
			"HideFromUI": "false",
			"EnchantCategory": "Attributes",
			"Cost": 1,
			"CursesItem": "false",
			"DurabilityDamage": 0,
			"StatusEffectsOnEquipIDs": [],
			"StatusEffectsOnLaunchIDs": [],
			"StatusEffectsOnAttackIDs": [],
			"AbilityModsOnEquipIDs": [],
			"OnEquipVisualEffects": [],
			"DamageProcs": [],
			"AbilitiesOnEquipIDs": ["285ed8bd-d40a-4709-b79e-1f5740d2916e"]
		}]
	},
        {
            "$type": "Game.GameData.LootListGameData, Assembly-CSharp",
            "DebugName": "MOD_Abydons_Ring_LL",
            "ID": "1e40fb40-c4cc-40dd-b9d6-89d24bbe9a32",
            "Components": [
                {
                    "$type": "Game.GameData.LootListComponent, Assembly-CSharp",
                    "Conditional": {
                        "Operator": 0,
                        "Components": []
                    },
                    "OutputChance": 1,
                    "OutputMode": "All",
                    "Items": [
                        {
                            "Conditional": {
                                "Operator": 0,
                                "Components": []
                            },
                            "OutputChance": 1,
                            "MinCount": 1,
                            "MaxCount": 1,
                            "Weight": 1,
                            "ItemID": "f77813b4-0cee-437f-8128-07391fea2e05",
                            "LootListID": "00000000-0000-0000-0000-000000000000",
                            "LockedVisible": "false"
                        }
                    ]
                }
            ]
        },
	{
			"$type": "Game.GameData.ModScriptHookGameData, Assembly-CSharp",
			"DebugName": "MOD_Abydons_Ring_Add",
			"ID": "b83388da-57b1-448f-9be9-296d588e88b7",
			"Components": [
				{
					"$type": "Game.GameData.ModScriptHookComponent, Assembly-CSharp",
					"RunOnlyOnce": "false",
					"SucceedOnlyOnce": "true",
					"Script": {
						"Conditional": {
							"Operator": 0,
							"Components": [
								{
									"$type": "OEIFormats.FlowCharts.ConditionalCall, OEIFormats",
									"Data": {
										"FullName": "Boolean IsInActiveScene(Guid)",
										"Parameters": [
											"2c8238c9-7a86-4394-b5e6-45c6a1d0bf10"
										]
									},
									"Not": false,
									"Operator": 0
								}
							]
						},
						"Scripts": [
							{
								"Data": {
									"FullName": "Void GenerateLootListInto(Guid, Guid)",
									"Parameters": [
										"2c8238c9-7a86-4394-b5e6-45c6a1d0bf10",
										"1e40fb40-c4cc-40dd-b9d6-89d24bbe9a32"
									]
								},
								"Conditional": {
									"Operator": 0,
									"Components": []
								}
							}
						]
					}
				}
			]
		}
	]
}

 

I also tried the spawning options swapping from true to false to both of them true. But it helped neither.

It cost me a whole night haha Maybe BMac knows what's wrong here 🙂

 

cheers

Edited by Phipanjo
grammar
Link to comment
Share on other sites

@Phipanjo If I replace '2c8238c9-7a86-4394-b5e6-45c6a1d0bf10' with the object GUID used in the example in the original post, I see your item in that store (Marihi's Metalworks). I don't know what your GUID is since I don't have the tools to search it up right now, but make sure it's an object GUID for a container or inventory in the store scene that's actually tied to that store. Also make sure your mod actually shows up in the Mod Manager, if not your folder structure may be the problem.

  • Thanks 1
Link to comment
Share on other sites

13 hours ago, BMac said:

@Phipanjo If I replace '2c8238c9-7a86-4394-b5e6-45c6a1d0bf10' with the object GUID used in the example in the original post, I see your item in that store (Marihi's Metalworks). I don't know what your GUID is since I don't have the tools to search it up right now, but make sure it's an object GUID for a container or inventory in the store scene that's actually tied to that store. Also make sure your mod actually shows up in the Mod Manager, if not your folder structure may be the problem.

Hi BMac, thanks for the answer!
I forgot to enable the cheat mode haha... Kinda took a whole night to get it 😅

But anyway... thanks for the script and your help, all works perfect now! 

cheers

Edited by Phipanjo
Link to comment
Share on other sites

  • 7 months later...

In the documentation it states that "Boolean expressions are evaluated right-to-left with no operator precendence." Am I correct in my understanding of this as: when a script tries to run it checks off all the conditions required, in the case of formatted json, from "bottom to top"? And if a condition is not met does it still go through the remaining list or does it stop checking at the first conditional that would stop the script from running?

Edited by Kvellen
Link to comment
Share on other sites

19 hours ago, Kvellen said:

In the documentation it states that "Boolean expressions are evaluated right-to-left with no operator precendence." Am I correct in my understanding of this as: when a script tries to run it checks off all the conditions required, in the case of formatted json, from "bottom to top"? And if a condition is not met does it still go through the remaining list or does it stop checking at the first conditional that would stop the script from running?

I looked at the code, and that comment definitely doesn't have enough detail to explain the behavior, which is, to be honest, bizarre.  Typically in Boolean algebra, R1 and R2 or R3 would be evaluated like (R1 and R2) or R3, but that's not the case here.  The conditionals are evaluated in order. If any AND conditional is false, the whole condition fails. If any OR conditional is true, the whole condition passes. In either case, evaluation will short-circuit (not evaluating any more conditionals).

If neither of those things occur, the result is based on the operator of the last conditional.

  • If it's AND, the result is RN (the result of the last conditional)
  • If it's OR, the result is RN OR RN-1

I'm not sure why it says "right-to-left". As far as I can tell, the evaluation order is left-to-right (top-to-bottom in JSON).

 

  • Thanks 2
Link to comment
Share on other sites

  • 10 months later...

cannot for the life of me get a scripted GenerateLootListInto to work, if i do it manually via console it works as intended, items from my lootlist get added to the targeted store(in this case, No-Nut Ned's) but if i do it via script, using the exact same guids, the items get added to Ned's inventory, not his store, so they cant be bought, they need to be looted from his corpse or pick-pocket'd, what am i doing wrong:

 

Quote

{
    "GameDataObjects": [
        {
            "$type": "Game.GameData.ModScriptHookGameData, Assembly-CSharp",
            "DebugName": "New_Items_For_Neds_Store",
            "ID": "29862625-8202-4002-90ce-480515d4b2e8",
            "Components": [
                {
                    "$type": "Game.GameData.ModScriptHookComponent, Assembly-CSharp",
                    "RunOnlyOnce": "false",
                    "SucceedOnlyOnce": "true",
                    "Script": {
                        "Conditional": {
                            "Operator": 0,
                            "Components": [
                                {
                                    "$type": "OEIFormats.FlowCharts.ConditionalCall, OEIFormats",
                                    "Data": {
                                        "FullName": "Boolean IsInActiveScene(Guid)",
                                        "Parameters": [
                                            "60560fd3-2a9e-4250-ac0f-4cefe6e6cd2d"
                                        ]
                                    },
                                    "Not": false,
                                    "Operator": 0
                                }
                            ]
                        },
                        "Scripts": [
                            {
                                "Data": {
                                    "FullName": "Void GenerateLootListInto(Guid, Guid)",
                                    "Parameters": [
                                        "60560fd3-2a9e-4250-ac0f-4cefe6e6cd2d",
                                        "0d3644ce-7785-40e3-ac43-df4470157a84"
                                    ]
                                },
                                "Conditional": {
                                    "Operator": 0,
                                    "Components": []
                                }
                            }]
                       }
                }]
        }]
}

image.png.1cd1ed35ff91b7f7071f86bc52290c4a.png

Edited by TKDancer
Link to comment
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
×
×
  • Create New...