Jump to content

[Request] Obsidian: Any chance we can get an example of the Vendor Object data so we can make our own Vendors in mods?


Recommended Posts

Pretty simple request...  I hope! :)

 

Right now we've figured out how to set the rates and discounts for an already established vendor (it's in factions.gamedatabundle) and how to change items sold by an already established vendor (by changing its LootListID found in items.gamedatabundle).    And we also know which UUID a vendor opens in its dialogue window (from its relevant conversationbundle).

 

What we DON'T have is an example of the actual Vendor Block that the UUID is a part of that presumably ties everything up in a package for the store.

 

In the Modding Documentation that was released in the Beta Patch tonight, there is the following:

 

 
Void OpenStore(Guid)
Scripts\Stores\Open Store
 
Name /type
 
Vendor
Guid (GameObject Instance ID)

 

 

 
Description /example
 
Vendor object to open.
"00000000-0000-0000-0000-000000000000"

As far as I know, we don't have any examples of a Vendor Object so we can make our own vendors/stores/inns/whatever.

 

I figure that in the definitions of the Vendor Object there is something that points to the VendorGameData found in factions.gamedatabundle and the LootListID found in items.gamedatabundle.

 

If it is at all possible, could an example of a vendor object that is calling be made so we can make our own?  And if inns/recruitment is handled differently, perhaps an example of those so we can make our own as well?

 

Thanks in advance for any help anyone from Obsidian might be able to provide. :)

Link to comment
Share on other sites

OK - which one in factions decides it?

 

This is the output from a gamedatabundle analysis tool I wrote

Array ( [0] => exported-1.1.1/design/gamedata/factions.gamedatabundle )
Types = 12

ChangeStrength - Game.GameData.ChangeStrengthGameData, Assembly-CSharp (3) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => ChangeStrengthComponent - Game.GameData.ChangeStrengthComponent, Assembly-CSharp (3) [5]
    => ReputationValue - integer(1)
    => DispositionValue - integer(1)
    => RelationshipValue - integer(1)
    => DisplayName - integer(4)
    => FormatString - integer(4)
Deity - Game.GameData.DeityGameData, Assembly-CSharp (7) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => DeityComponent - Game.GameData.DeityComponent, Assembly-CSharp (7) [3]
    => DisplayName - integer(4)
    => PositiveDispositionsIDs - string(79)
    => NegativeDispositionsIDs - string(79)
Disposition - Game.GameData.DispositionGameData, Assembly-CSharp (10) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => DispositionComponent - Game.GameData.DispositionComponent, Assembly-CSharp (10) [5]
    => DisplayName - integer(4)
    => Description - integer(2)
    => Ranks - string(20)
    => Icon - string(38)
    => CircularIcon - string(44)
Faction - Game.GameData.FactionGameData, Assembly-CSharp (13) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => FactionComponent - Game.GameData.FactionComponent, Assembly-CSharp (13) [14]
    => DisplayName - integer(4)
    => IsMajorFaction - boolean(1)
    => Scale - integer(2)
    => GlossaryEntryID - string(36)
    => Positive - integer(1)
    => Negative - integer(1)
    => Icon - string(52)
    => IconRound - string(53)
    => FlagIcon - string(1)
    => FlagIconSmall - string(52)
    => FlagIconCombat - string(55)
    => HideFromReputationUI - boolean(1)
    => ReputationCanChangeRelationship - boolean(1)
    => ReputationScripts - string(336)
MetaTeam - Game.GameData.MetaTeamGameData, Assembly-CSharp (5) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => MetaTeamComponent - Game.GameData.MetaTeamComponent, Assembly-CSharp (5) [1]
    => TeamListIDs - string(196)
PaladinOrder - Game.GameData.PaladinOrderGameData, Assembly-CSharp (7) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => PaladinOrderComponent - Game.GameData.PaladinOrderComponent, Assembly-CSharp (7) [3]
    => DisplayName - integer(4)
    => PositiveDispositionsIDs - string(79)
    => NegativeDispositionsIDs - string(79)
ReputationRank - Game.GameData.ReputationRankGameData, Assembly-CSharp (16) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => ReputationRankComponent - Game.GameData.ReputationRankComponent, Assembly-CSharp (16) [8]
    => Title - integer(2)
    => Rank - integer(1)
    => RankType - string(7)
    => PositiveValue - integer(1)
    => NegativeValue - integer(1)
    => ForceRelationChange - boolean(1)
    => CallFactionScripts - boolean(1)
    => VendorRatesID - string(36)
ReputationThreshold - Game.GameData.ReputationThresholdGameData, Assembly-CSharp (2) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => ReputationThresholdComponent - Game.GameData.ReputationThresholdComponent, Assembly-CSharp (2) [2]
    => Axis - string(
    => Thresholds - string(22)
ShipHostilit - Game.GameData.ShipHostilityManager, Assembly-CSharp (1) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => ShipHostilityManagerComponent - Game.GameData.ShipHostilityManagerComponent, Assembly-CSharp (1) [2]
    => FactionHostilitySets - string(5455)
    => CaptainOverrides - string(9777)
Team - Game.GameData.TeamGameData, Assembly-CSharp (336) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => TeamComponent - Game.GameData.TeamComponent, Assembly-CSharp (336) [8]
    => FactionID - string(36)
    => DefaultRelationship - string(
    => TeamType - string(6)
    => HostileTeamsIDs - string(40)
    => NeutralTeamsIDs - string(157)
    => FriendlyTeamsIDs - string(274)
    => InjuredReputationChangeID - string(36)
    => MurderedReputationChangeID - string(36)
Vendor - Game.GameData.VendorGameData, Assembly-CSharp (69) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => VendorComponent - Game.GameData.VendorComponent, Assembly-CSharp (69) [6]
    => VendorName - integer(3)
    => StoreIconPath - string(38)
    => PortraitPath - string(58)
    => StartingFactionID - string(36)
    => ConditionalRates - string(399)
    => LockedDescriptionString - integer(2)
VendorRates - Game.GameData.VendorRatesGameData, Assembly-CSharp (10) - exported-1.1.1/design/gamedata/factions.gamedatabundle
  => VendorRatesComponent - Game.GameData.VendorRatesComponent, Assembly-CSharp (10) [3]
    => SellMultiplier - double(1)
    => BuyMultiplier - double(1)
    => InnMultiplier - double(1)
12 - 12 - 60
12 ctypes
'ChangeStrengthComponent', 'DeityComponent', 'DispositionComponent', 'FactionComponent', 'MetaTeamComponent', 'PaladinOrderComponent', 'ReputationRankComponent', 'ReputationThresholdComponent', 'ShipHostilityManagerComponent', 'TeamComponent', 'VendorComponent', 'VendorRatesComponent

12 ttypes
'ChangeStrength', 'Deity', 'Disposition', 'Faction', 'MetaTeam', 'PaladinOrder', 'ReputationRank', 'ReputationThreshold', 'ShipHostilit', 'Team', 'Vendor', 'VendorRates'

I'm guessing ConditionalRates or one of the Multipliers

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

OK - which one in factions decides it?

 

it's super late at night here in California, so I'll look more deeply at what you posted later.  But as an example:

 

Here is the entry for the Cartographer, Sanza, in factions.gamedatabundle:

{
			"$type": "Game.GameData.VendorGameData, Assembly-CSharp",
			"DebugName": "Vendor_03_Cartographer",
			"ID": "8d2d92e7-8a24-49bf-a2ba-542046f61e2a",
			"Components": [{
					"$type": "Game.GameData.VendorComponent, Assembly-CSharp",
					"VendorName": 143,
					"StoreIconPath": "gui/innicons/storesign_generic.png",
					"PortraitPath": "",
					"StartingFactionID": "1346f12d-ca42-4add-9599-aa3fe72f5e53",
					"ConditionalRates": [],
					"LockedDescriptionString": -1
				}
			]
		}

StartingFactionID points to this in the same file:

{
			"$type": "Game.GameData.FactionGameData, Assembly-CSharp",
			"DebugName": "FCT_00_Neketaka",
			"ID": "1346f12d-ca42-4add-9599-aa3fe72f5e53",
			"Components": [{
					"$type": "Game.GameData.FactionComponent, Assembly-CSharp",
					"DisplayName": 32,
					"IsMajorFaction": "true",
					"Scale": 50,
					"GlossaryEntryID": "90c1f2a4-9056-4d9f-845a-881ff722e4d2",
					"Positive": 0,
					"Negative": 0,
					"Icon": "",
					"IconRound": "gui/icons/gamesystems/reputationicon_neketaka.png",
					"FlagIcon": "",
					"FlagIconSmall": "",
					"FlagIconCombat": "",
					"HideFromReputationUI": "false",
					"ReputationCanChangeRelationship": "false",
					"ReputationScripts": [{
							"RankType": "Default",
							"Script": {
								"GuidString": "00000000-0000-0000-0000-000000000000"
							}
						}, {
							"RankType": "Good",
							"Script": {
								"GuidString": "00000000-0000-0000-0000-000000000000"
							}
						}, {
							"RankType": "Bad",
							"Script": {
								"GuidString": "00000000-0000-0000-0000-000000000000"
							}
						}, {
							"RankType": "Mixed",
							"Script": {
								"GuidString": "00000000-0000-0000-0000-000000000000"
							}
						}
					]
				}
			]
		}

It's the data for the Neketaka 'faction', for the record. Which means he will use your reputation with Neketaka to set his rates. 

 

Other vendors might use something different.  For instance, the shipyard master in Nekataka has a conditional rate (as defined by RatesID) which will override his normal Neketaka rate if the condition is met:

{
			"$type": "Game.GameData.VendorGameData, Assembly-CSharp",
			"DebugName": "Vendor_03_VD_Shipyard",
			"ID": "8aa9c42d-b89e-4686-acf7-b9f230b1ff35",
			"Components": [{
					"$type": "Game.GameData.VendorComponent, Assembly-CSharp",
					"VendorName": 441,
					"StoreIconPath": "gui/innicons/storesign_generic.png",
					"PortraitPath": "",
					"StartingFactionID": "1346f12d-ca42-4add-9599-aa3fe72f5e53",
					"ConditionalRates": [{
							"RatesID": "d9ec906b-3f4c-4507-9cf1-235b466fbbc8",
							"Condition": {
								"Operator": 0,
								"Components": [{
										"$type": "OEIFormats.FlowCharts.ConditionalCall, OEIFormats",
										"Data": {
											"FullName": "Boolean IsGlobalValue(String, Operator, Int32)",
											"Parameters": ["n_Shipwrights_Plight_main", "GreaterThanOrEqualTo", "4"],
											"Flags": "",
											"UnrealCall": "",
											"FunctionHash": 901380568,
											"ParameterHash": 2107384759
										},
										"Not": false,
										"Operator": 0
									}
								]
							}
						}
					],
					"LockedDescriptionString": -1
				}
			]
		},

So just where ARE rates defined? Either via your faction rep or via a conditional.  It's elsewhere in factions in this block (it's long, so I'll spoilerize it):

 

 

{
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Bad_01",
			"ID": "70f062d8-5edc-43b5-8e32-f0ecbd7a9c9d",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 1.1,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 1.1
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Bad_02",
			"ID": "8b1371c6-9917-4afd-92cd-24bcbb7354d4",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 1.2,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 1.2
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Bad_03",
			"ID": "3aef39c3-757f-49c3-a5d9-299ff730409b",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 1.3,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 1.3
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Beraths_Blessings",
			"ID": "42c0f93d-ce7c-494c-a637-c7949fc4cbf2",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 0.5,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 0.5
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Default",
			"ID": "bd6efb6b-45e0-477f-b80e-95931b37fa53",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 1,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 1
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Free",
			"ID": "880953e4-2052-456e-a622-eab7e9359776",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 0,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 0
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Good_1",
			"ID": "9e0a47e0-5103-44c7-973f-321316e9feeb",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 0.95,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 0.95
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Good_2",
			"ID": "d9ec906b-3f4c-4507-9cf1-235b466fbbc8",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 0.9,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 0.9
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Good_3",
			"ID": "dda88477-0aa3-4992-bd7f-0fc4b2394e45",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 0.85,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 0.85
				}
			]
		}, {
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Good_WM",
			"ID": "ebe5a3f2-4f77-4b18-b655-4e355982d9ea",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 0.5,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 0.5
				}
			]
		 

 

 

 

The in-game threshold for Good/Bad/Mixed is ALSO defined in the factions gamebundle but it isn't quite as relevant to the question, I think so I'll skip on that for now.

 

====

 

In short, normally a vendor is  tied to a faction reputation (which eventually winds its way to that rate list I provided) OR it goes to a specially defined block via the ConditionalRate like the ones for the Berath's Blessing seller in Port Maje and the various World Map sellers OR nothing at all (in that case it has an empty UUID in its StartingFactionID).  As an aside, that empty UUID in the StartingFactionID is why some vendors never give a discount to some folks.

 

 

This means one could set up one's own seller discounts by tying it to a (set of) made-up UUIDs.  Just follow the template of this:

{
			"$type": "Game.GameData.VendorRatesGameData, Assembly-CSharp",
			"DebugName": "Rates_Good_WM",
			"ID": "ebe5a3f2-4f77-4b18-b655-4e355982d9ea",
			"Components": [{
					"$type": "Game.GameData.VendorRatesComponent, Assembly-CSharp",
					"SellMultiplier": 0.5,
					"BuyMultiplier": 0.2,
					"InnMultiplier": 0.5
				}
			]
		}

to set whatever multipliers you want.

 

Then put the new ID of that code you created in RatesID, while changing the ID, VendorName, and Debug Names to whatever you want, using this as a template: 

{
			"$type": "Game.GameData.VendorGameData, Assembly-CSharp",
			"DebugName": "Vendor_WM_Huana_Rice_Farm",
			"ID": "b6c37866-ac59-4fe4-a475-3668f7c8addb",
			"Components": [{
					"$type": "Game.GameData.VendorComponent, Assembly-CSharp",
					"VendorName": 622,
					"StoreIconPath": "gui/innicons/storesign_generic.png",
					"PortraitPath": "",
					"StartingFactionID": "00000000-0000-0000-0000-000000000000",
					"ConditionalRates": [{
							"RatesID": "ebe5a3f2-4f77-4b18-b655-4e355982d9ea",
							"Condition": {
								"Operator": 0,
								"Components": [{
										"$type": "OEIFormats.FlowCharts.ConditionalCall, OEIFormats",
										"Data": {
											"FullName": "Boolean AlwaysTrue()",
											"Parameters": [],
											"Flags": "",
											"UnrealCall": "",
											"FunctionHash": 837405672,
											"ParameterHash": 837405672
										},
										"Not": false,
										"Operator": 0
									}
								]
							}
						}
					],
					"LockedDescriptionString": -1
				}
			]
		}

Should be able to set all sorts of fun conditions, given the examples already seen in that file and elsewhere in the game.

 

I'm fairly sure the way this block is written is that it makes the condition Always True, which means one always gets the 50% discount no matter what happens in the game.

 

================

 

Not exactly sure if that's the info you wanted or not.  But hopefully it's of use to someone. :)

 

(anything else I'll have to look at in the morning as it is waaaaay past my bedtime here on the Left Coast)

 

----------------------

 

edited.

 

What the hey.  The Good/Mixed/Bad thresholds (spoilered because it is hella long):

 

 

 

{
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Bad1",
			"ID": "e1c73bd9-c80e-4a27-be28-6f887df5b013",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 3,
					"Rank": 1,
					"RankType": "Bad",
					"PositiveValue": 0,
					"NegativeValue": 1,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "70f062d8-5edc-43b5-8e32-f0ecbd7a9c9d"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Bad2",
			"ID": "0380402b-d2ff-419a-9341-5f3a70905ca0",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 4,
					"Rank": 2,
					"RankType": "Bad",
					"PositiveValue": 1,
					"NegativeValue": 2,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "70f062d8-5edc-43b5-8e32-f0ecbd7a9c9d"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Bad3",
			"ID": "f7a6b03a-7fa9-45fe-b8e6-6a2cadd55877",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 5,
					"Rank": 3,
					"RankType": "Bad",
					"PositiveValue": 0,
					"NegativeValue": 2,
					"ForceRelationChange": "true",
					"CallFactionScripts": "false",
					"VendorRatesID": "8b1371c6-9917-4afd-92cd-24bcbb7354d4"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Bad4",
			"ID": "f86e6ebd-9633-4482-921a-1ee255381ffe",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 6,
					"Rank": 4,
					"RankType": "Bad",
					"PositiveValue": 1,
					"NegativeValue": 3,
					"ForceRelationChange": "true",
					"CallFactionScripts": "false",
					"VendorRatesID": "8b1371c6-9917-4afd-92cd-24bcbb7354d4"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Bad5",
			"ID": "d94739ad-89a5-489d-8bd5-b36126265ee4",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 7,
					"Rank": 5,
					"RankType": "Bad",
					"PositiveValue": 0,
					"NegativeValue": 3,
					"ForceRelationChange": "true",
					"CallFactionScripts": "false",
					"VendorRatesID": "3aef39c3-757f-49c3-a5d9-299ff730409b"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Default",
			"ID": "b93a2b76-62a7-4892-af43-1f47aeccb113",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 2,
					"Rank": 0,
					"RankType": "Default",
					"PositiveValue": 0,
					"NegativeValue": 0,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "bd6efb6b-45e0-477f-b80e-95931b37fa53"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Good1",
			"ID": "16701d4b-5195-4dab-930d-6dcd09846064",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 8,
					"Rank": 1,
					"RankType": "Good",
					"PositiveValue": 1,
					"NegativeValue": 0,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "9e0a47e0-5103-44c7-973f-321316e9feeb"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Good2",
			"ID": "0dc3ca7a-048c-4781-86ef-c9420c5a4b40",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 9,
					"Rank": 2,
					"RankType": "Good",
					"PositiveValue": 2,
					"NegativeValue": 1,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "9e0a47e0-5103-44c7-973f-321316e9feeb"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Good3",
			"ID": "a1d62b93-7386-4dea-9ab7-46d4ddce1921",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 10,
					"Rank": 3,
					"RankType": "Good",
					"PositiveValue": 2,
					"NegativeValue": 0,
					"ForceRelationChange": "true",
					"CallFactionScripts": "false",
					"VendorRatesID": "d9ec906b-3f4c-4507-9cf1-235b466fbbc8"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Good4",
			"ID": "245068c9-48ce-4940-bc26-6821ba80ce74",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 11,
					"Rank": 4,
					"RankType": "Good",
					"PositiveValue": 3,
					"NegativeValue": 1,
					"ForceRelationChange": "true",
					"CallFactionScripts": "false",
					"VendorRatesID": "d9ec906b-3f4c-4507-9cf1-235b466fbbc8"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Good5",
			"ID": "ebf43f6c-23d2-4ea2-899a-a1d3bf827d7e",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 12,
					"Rank": 5,
					"RankType": "Good",
					"PositiveValue": 3,
					"NegativeValue": 0,
					"ForceRelationChange": "true",
					"CallFactionScripts": "false",
					"VendorRatesID": "dda88477-0aa3-4992-bd7f-0fc4b2394e45"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Mixed1",
			"ID": "8e7230ee-49fb-4fcf-aa5e-552b7e50e25d",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 13,
					"Rank": 1,
					"RankType": "Mixed",
					"PositiveValue": 1,
					"NegativeValue": 1,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "bd6efb6b-45e0-477f-b80e-95931b37fa53"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Mixed2",
			"ID": "48227a87-7f6e-4f4e-ab7d-5f14694d115d",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 14,
					"Rank": 2,
					"RankType": "Mixed",
					"PositiveValue": 2,
					"NegativeValue": 2,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "bd6efb6b-45e0-477f-b80e-95931b37fa53"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Mixed3",
			"ID": "fb3b2325-2ad1-4a2f-9edc-3b4e1b86dfe7",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 15,
					"Rank": 3,
					"RankType": "Mixed",
					"PositiveValue": 2,
					"NegativeValue": 3,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "bd6efb6b-45e0-477f-b80e-95931b37fa53"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Mixed4",
			"ID": "ad7364ce-dff2-4ebf-8081-2099f0f8aa00",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 16,
					"Rank": 4,
					"RankType": "Mixed",
					"PositiveValue": 3,
					"NegativeValue": 2,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "bd6efb6b-45e0-477f-b80e-95931b37fa53"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationRankGameData, Assembly-CSharp",
			"DebugName": "Mixed5",
			"ID": "e056ebcd-f910-423a-bfb7-d2a7340c0c16",
			"Components": [{
					"$type": "Game.GameData.ReputationRankComponent, Assembly-CSharp",
					"Title": 17,
					"Rank": 5,
					"RankType": "Mixed",
					"PositiveValue": 3,
					"NegativeValue": 3,
					"ForceRelationChange": "false",
					"CallFactionScripts": "false",
					"VendorRatesID": "bd6efb6b-45e0-477f-b80e-95931b37fa53"
				}
			]
		}, {
			"$type": "Game.GameData.ReputationThresholdGameData, Assembly-CSharp",
			"DebugName": "BadThresholds",
			"ID": "5fcc8b47-b54c-4ee0-873e-85774db5a838",
			"Components": [{
					"$type": "Game.GameData.ReputationThresholdComponent, Assembly-CSharp",
					"Axis": "Negative",
					"Thresholds": ["0", "0.15", "0.5", "1"]
				}
			]
		}, {
			"$type": "Game.GameData.ReputationThresholdGameData, Assembly-CSharp",
			"DebugName": "GoodThresholds",
			"ID": "1ba0a2e1-6bde-4194-b8f2-5bc8cd68abd8",
			"Components": [{
					"$type": "Game.GameData.ReputationThresholdComponent, Assembly-CSharp",
					"Axis": "Positive",
					"Thresholds": ["0", "0.15", "0.5", "1"]
				}
		

 

 

 

In each of those Good/Mixed/Bad blocks there is the corresponding VendorRate associated with that level of Good/Bad/Mixedm which I already posted.  That's how the game will know how to interpret, say, a Faction Good Rank of 4 into a 10% discount or how to interpret a Faction Bad Rank of 5 into a 15% surcharge.  And so on and so on and so on.

 

This ALSO means we could set our own discount rates for each level of Good/Bad/Mixed via a mod if we so choose.  Including the buying items from the player, which at the moment is static across all ranks.

Edited by Zap Gun For Hire
Link to comment
Share on other sites

See https://forums.obsidian.net/topic/103067-all-the-uuids-listed/

 

That abstracts this problem and explains it.

 

Basically there will be no connection between the two other than level20 which in the post above I use as an example of Sanza and his shop. I read your post before writing that one so I give you a few personal clues in the thread.

 

I've mentioned to the devs this disconnect - I think I'll push this one a little harder - the only way to currently find out the linkage is full analysis of 30Gb (takes 8 mins per query, hence the other post where I've done most of the 'homework')

 

I can't CC a PM but basically what I'll be asking for is linkage so Sanza has Sanza's Shop which contains Spyglass etc and is a member of [some] faction where we can apply discounts.

 

You doing the Economy mod then?

 

I've not looked at factions properly yet but it's got some keys that obviously affect the economy

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

OK

 

Had a ****-load of other stuff to do (many posts etc)

 

Now I've got a bit of free time I'll have a proper look into yours

 

I'll let you do the release

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

Bugger

 

Just opened factions and instantly found your references

 

My eyesight (I'm an old dude) is a bit dodgy - specs time - ooh - I can see again! :)

 

My intention is to write a private Mod and give it to you to re-work for publication

 

More info when I've played around

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

OK think I know how this one works now

 

Mod time

 

See ya later

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

Bugger

 

Just opened factions and instantly found your references

 

My eyesight (I'm an old dude) is a bit dodgy - specs time - ooh - I can see again! :)

 

My intention is to write a private Mod and give it to you to re-work for publication

 

More info when I've played around

 

I'm not planning on doing any sort of public mods for quite a while, if I ever do, for Deadfire.  So go ahead and release anything you'd like in regards to this under your own name over at Nexus and here.  :thumbsup:

 

If you'd like my help behind the scenes before you release something, I could see what I can do to help though. :)

Link to comment
Share on other sites

Yeah

 

I'm not gonna get through factions tonite anyway

 

As requed I wrote a howto [insert anything here] - actually, didn't you ask for this one?

 

Dunno, just know it was a good req worthy of an expain

 

BMac's just opened up the docs (I was at the end of the vendor doc at the time) - better go read them

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

 actually, didn't you ask for this one?

 

No. not quite.  What I'm asking for is an example of a Vendor Object itself, which we don't have access to.  That way we can make ANY character a Vendor using that as a guide.  Theoretically we could make any character have MULTIPLE stores by adding new dialogue, which  sets aside a concern for duplication.  

 

It goes back to the bit in the first post of this thread:

 

 

What we DON'T have is an example of the actual Vendor Block that the UUID is a part of that presumably ties everything up in a package for the store.

 

In the Modding Documentation that was released in the Beta Patch tonight, there is the following:

 

 
Void OpenStore(Guid)
Scripts\Stores\Open Store
 
Name /type
 
Vendor
Guid (GameObject Instance ID)

 

 

 
Description /example
 
Vendor object to open.
"00000000-0000-0000-0000-000000000000"

As far as I know, we don't have any examples of a Vendor Object so we can make our own vendors/stores/inns/whatever.

 

In short, we can modify an already existing store , as you showed.  What we can't do, as far as I know, is make an entierly new store out of whole cloth and assign it to a NPC who isn't already a vendor.

 

Thus my request to the Obsidian Devs for an example. Once we know what a Vendor Object looks like, we should be able to make our own stores for any NPC in the game.

Edited by Zap Gun For Hire
Link to comment
Share on other sites

Oh - that one

 

Been there, done it - it's not hard (just messy)

 

This crap requires a convo logic manipulation - you can't do a store but you can give items away with ease

 

Sadly this involves major hacks to the *conversationbundles and conversations/[language]/.../.../*stringtables

 

I had the same goal and this was the only surefire way to resolve it

 

I took Waenglith (Port Maje) and altered her so something silly - "Give me a kipper"

 

After numerous rounds I got her to give me something (anything)

 

I then extracted the translations of "Show me what you have" and did localised versions I assume to be correct.

 

At that point I was helping TT1 solve an issue with Dead Parrot so I hacked that down to level 1 and eventually solved his issue

 

After this I went back to Waenglith (near the square in Port Maje where you get Xoti) on a do or die sorta misson

 

I didn't die :)

 

Owing to a screw up I've lost the code but know how to do it

 

The problem is that ATM I have to write outside override - something I don't wanna do

 

I can show you a Waenglith mod that provides any item

 

I have SO many dead parrots now...

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

This crap requires a convo logic manipulation - you can't do a store but you can give items away with ease

No worries on that score.  I already know how to get items from folks for free. :)  Just add "Void GiveItems(Guid, Int32)" with the right parameters call to a given node in the appropriate OnEnterScripts/OnExitScripts.  (I also made sure to get rid of the UnrealCall associated with it, just to be sure)

 

That was quite literally one of the first things I learned to do when I was modding PoE I for myself.  Daddy wanted some of those Unique Items that he couldn't get. :lol:

Edited by Zap Gun For Hire
Link to comment
Share on other sites

Anyway, back to the request I made for the Devs in my first post. :)

 

============

 

We know how to make an entirely new item for the game, because we have examples to follow from the items in items.gamedatabundles.

 

We know how to add/subtract to already existing stores, or any container for that matter, thanks to the already existing LootList examples.

We can make new status effects, abilities, and attacks thanks to the examples we can use as a guide in the various gamedatabundles.

 

What ***I*** can't do is make an entirely new store and assign it to a new character because I don't know how, to pick as an example because it's handy, the UUID ("faafe4d0-16e3-4d76-8b34-6d42132ecd84") in the following block (from Sanza's conversationbundle):

			"OnExitScripts": [
				{
					"Data": {
						"FullName": "Void OpenStore(Guid)",
						"Parameters": [
							"faafe4d0-16e3-4d76-8b34-6d42132ecd84"
						],
						"UnrealCall": "",
						"FunctionHash": 215165789,
						"ParameterHash": 44899091
					},
					"Conditional": {
						"Operator": 0,
						"Components": []
					}
				}
			],

actually knows how to call the LootListGameData of ("1522b748-9761-4c17-981c-ebe76dfc5127") [his store data from items.gamedatabundle] and the VendorGameData of ("8d2d92e7-8a24-49bf-a2ba-542046f61e2a") [his rates data from factions.gamedatabundle]

 

IF we knew how the game knew how tie together those three things, we should be able to make any NPC anywhere a vendor, simply by using that example as a guide. :)

 

NOTE:::: I'm not asking to change Sanza's shop.  I think we've covered that it's possible to do that. ;)  I'm simply using Sanza as an concrete example of what we DON'T know, not because I'm particularly interested in his shop.

Edited by Zap Gun For Hire
Link to comment
Share on other sites

Turns out that setting all the multipliers to 0.2 yields a flat economy.

 

Baked in there's a 5x multiplier so 0.2 results in an 80% discount resulting in full value for sale or purchase of anything.

 

This solves an old req for a mod so I may as well publish it.

 

I'll credit you in the Mod (your 15 mins of fame has begun :))

 

I did a version where the Multipliers were 0.0 but that looked really sucky - everything cost and sold for 0cp :(

  • Like 1

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

Mind, if it's not possible to make an entirely new store/inn/whatever via a mod on our end quite yet, that's be good to know as well, Obsidian. :)  

 

I'll write up my unreleased Waenglith Mod - with luck I'll get to do it today

 

The reason it's not released if I'm waiting for design/conversations to be moddable

 

What I can show is how to add an option to her that does something

 

Come to think of it I'll do FishMonger in Port Maje again as it don't matter much if you screw her up

 

The current issue is that as we have no way to mod conversations in override you HAVE to mod the main exported branch

 

You can't create a new shop but you CAN give people things (I had loads of Dead Parrot's before I managed to delete the data directory)

 

I've got a script file that makes it simple for me to build most of it with multi-lingual translations (I just pinched some text from other vendor stringtables)

 

I won't release a Mod based on these experiments but they are useful for local tests. As far as I'm concerned anything out of override is not a Mod (it's a hack)

 

When they fix convo modding exactly the same concept will apply to the modded convos so it's worth educating people in the methodology before they fix it.

 

Something I plan is the Chest Of Consumables - I'll stick it on a useless NPC (Captain Darmo in PM) not heard of him - see completely forgettable

 

There are prob 500 - 1,000 equally useless NPCs in POE2 that are worthy of doing useful things so when we get override this becomes a useful technique

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Link to comment
Share on other sites

This is a lot to catch up on, but it's probably going to be prohibitively difficult to add an entirely new vendor to the game because important data for doing so is in the Unity scene, not game data.  There's a Vendor object in the scene (this is the object referred to by OpenStore) that ties together a number of different containers (also in the scene), some visible and some not.  This is why you see different behavior from different loot lists - some of the loot lists are used to generate those containers (the first time that scene is loaded), which others are used to regenerate hidden inventories full of less-unique items.  All of this is specified on Unity components in the scene.

  • Like 2
Link to comment
Share on other sites

This is a lot to catch up on, but it's probably going to be prohibitively difficult to add an entirely new vendor to the game because important data for doing so is in the Unity scene, not game data.  There's a Vendor object in the scene (this is the object referred to by OpenStore) that ties together a number of different containers (also in the scene), some visible and some not.  This is why you see different behavior from different loot lists - some of the loot lists are used to generate those containers (the first time that scene is loaded), which others are used to regenerate hidden inventories full of less-unique items.  All of this is specified on Unity components in the scene.

Was afraid that was the case, but thanks for the confirmation anyway.  :thumbsup:

Link to comment
Share on other sites

Could you code an alternative vendor type via conversations and scripts (I have not dabbled in this area yet) where you can buy limited unique options if you choose a conversation option, do a hasfunds check (whatever the boolean is) and then a confirmation and giveitem/remove money?

 

These NPCs wouldn't be conventional vendors but "pssst hey over here, I've got these 5 special items you can buy".

Link to comment
Share on other sites

Could you code an alternative vendor type via conversations and scripts (I have not dabbled in this area yet) where you can buy limited unique options if you choose a conversation option, do a hasfunds check (whatever the boolean is) and then a confirmation and giveitem/remove money?

 

These NPCs wouldn't be conventional vendors but "pssst hey over here, I've got these 5 special items you can buy".

Since we can now easily (or at least more easily) override conversation bundles, this should be relatively doable.  The modder in question would have to have a fairly good understanding of the node structure of conversations, as well as the Enter/Exit scripts.  But once that is understood it becomes somewhat trivial.

 

Emphasis on SOMEWHAT. :lol:

 

Also would need a corresponding stringtable for the new dialogue options.  But just 'buying'/'selling' things via a conversation dialogue is doable as there are quite a few examples already present in the game to use as a guide.  

 

===

 

There are checks in the game to see if the player has enough gold on hand, can remove items/gold from the player's inventory and can check to see how many items someone has in their inventory.

 

The one thing I don't know is if modders can create their own custom variables.  If they can, then even the number of items someone has bought from someone can be tracked in conversations bundles.  

 

And even if custom variables can't be made, there's an check to see if a specific dialogue node has been called or not.  That can be used as a backdoor logic gate on an item.

 

It could go something like this:

 

Node 50: "Hey, I'd like the buy the Infinity Plus One Sword."

Node 51: Check to see if player has funds

Node 52: NPC: "It'll cost you 10000 gold.  Still want it?"

Node 53: "yes" option displayed

Node 54: "no" option displayed

Node 55 (If yes): Check to see if Node 70 has been called.  If yes, go to Node 65.  If no subtract gold; Give Item; go to Node 70

Node 56 (if no): NPC: Fair enuf, guvner.  Anything else?

Node 65 (if already bought):  NPC: "Fresh out of stock.  Better luck next time."

Node 70 (if not already bought): NPC: "Here you are.  Last one I had."

 

More or less.  Something like that, at least.  I think. :lol:  Might have some of the node structure messed up.

 

Have to make sure there's  the actual directions to go from one node to another, and I'm kinda (i.e. hugely) simplifying the above.  Could also probably be compacted more than a bit.  But as a logic path, that's more or less how to make it so a character can buy exactly one item IF custom variables can't be created

Edited by Zap Gun For Hire
Link to comment
Share on other sites

I knew all the boolean checks are available (I've waded through them but couldn't remember exact names) but I haven't looked at conversation bundles.  Looks like ai decision trees which I have been messing with.  Shouldn't be too hard - just time consuming.  But all modding is.  Could be the way forward for unique item vendors - especally once templated by whoever does it first. ;)

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...